.Net.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks; namespace SocketIM
{
////// Net : 提供静态方法,对常用的网络操作进行封装
public class Net
{
public class ObjectState
{
public string fileName { get; set; }
public Socket workSocket { get; set; }
public Thread workThread { get; set; }
}
private Net()
{
} ////// 向远程主机发送数据
//////要发送数据且已经连接到远程主机的 Socket///待发送的数据///发送数据的超时时间,以秒为单位,可以精确到微秒///0:发送数据成功;-1:超时;-2:发送数据出现错误;-3:发送数据时出现异常////// 当 outTime 指定为-1时,将一直等待直到有数据需要发送
public static int SendData(Socket socket, byte[] buffer, int outTime)
{
if (socket == null || socket.Connected == false)
{
throw new ArgumentException("参数socket 为null,或者未连接到远程计算机");
}
if (buffer == null || buffer.Length == )
{
throw new ArgumentException("参数buffer 为null ,或者长度为 0");
} int flag = ;
try
{
int totalLen = buffer.Length;
int sndLen = ; while (true)
{
if ((socket.Poll(outTime * , SelectMode.SelectWrite) == true))
{ // 收集了足够多的传出数据后开始发送
sndLen = socket.Send(buffer, sndLen, totalLen, SocketFlags.None);
totalLen -= sndLen;
if (totalLen == )
{ // 数据已经全部发送
flag = ;
break;
}
else
{
if (sndLen > )
{ // 数据部分已经被发送continue;
}
else
{ // 发送数据发生错误
flag = -;
break;
}
}
}
else
{ // 超时退出
flag = -;
break;
}
}
}
catch (SocketException e)
{ flag = -;
}
return flag;
} ////// 向远程主机发送文件
//////要发送数据且已经连接到远程主机的 socket///待发送的文件名称///文件发送时的缓冲区大小///发送缓冲区中的数据的超时时间///0:发送文件成功;-1:超时;-2:发送文件出现错误;-3:发送文件出现异常;-4:读取待发送文件发生错误////// 当 outTime 指定为-1时,将一直等待直到有数据需要发送
public static int SendFile(string ip, int port, string fileName, int maxBufferLength, int outTime)
{
IPAddress address = IPAddress.Parse(ip);
IPEndPoint endpoint = new IPEndPoint(address, port);
//创建服务端负责监听的套接字,参数(使用IPV4协议,使用流式连接,使用TCO协议传输数据)
Thread.Sleep();
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Connect(endpoint);
if (socket.Connected)
{
Console.WriteLine(socket.RemoteEndPoint + "连接成功");
}
if (fileName == null || maxBufferLength <= )
{
throw new ArgumentException("待发送的文件名称为空或发送缓冲区的大小设置不正确.");
}
int flag = ;
try
{
FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
long fileLen = fs.Length; // 文件长度
long totalLen = fileLen; // 未读取部分
int readLen = ; // 已读取部分
byte[] buffer = null; if (fileLen <= maxBufferLength)
{ /* 文件可以一次读取*/
buffer = new byte[fileLen];
readLen = fs.Read(buffer, , (int)fileLen);
flag = SendData(socket, buffer, outTime);
}
else
{
/* 循环读取文件,并发送 */
while (totalLen != )
{
if (totalLen < maxBufferLength)
{
buffer = new byte[totalLen];
readLen = fs.Read(buffer, , Convert.ToInt32(totalLen));
}
else
{
buffer = new byte[maxBufferLength];
readLen = fs.Read(buffer, , maxBufferLength);
}
if ((flag = SendData(socket, buffer, outTime)) < )
{
break;
}
totalLen -= readLen;
}
}
fs.Flush();
fs.Close();
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
catch (IOException e)
{ flag = -;
}
if (flag == )
{
Console.WriteLine(fileName + "文件发送成功");
socket.Close();
Console.WriteLine("连接关闭");
}
else
{
Console.WriteLine(fileName + "文件发送失败,i=" + flag);
}
return flag;
}
private static void WatchConnecting(object info)
{
ObjectState state = (ObjectState)info;
Socket socketWatch = state.workSocket;
while (true)//持续不断的监听客户端的请求
{
//开始监听 客户端连接请求,注意:Accept方法,会阻断当前的线程
Socket connection = socketWatch.Accept(); if (connection.Connected)
{ //创建通信线程
Thread thradRecMsg = new Thread(RecMsg);
state.workSocket = connection;
state.workThread = thradRecMsg;
thradRecMsg.IsBackground = true;
thradRecMsg.Start(state); }
} }
////// 接收消息
private static void RecMsg(object socketClientPara)
{ ObjectState state = (ObjectState)socketClientPara;
string fileName = state.fileName;//$@"d:HQ.dat";//获得用户保存文件的路径
Socket socketClient = state.workSocket;
FileStream fs = null;
while (true)
{
//定义一个接受用的缓存区(100M字节数组)
//将接收到的数据存入arrMsgRec数组,并返回真正接受到的数据的长度
if (socketClient.Connected)
{
try
{
//因为终端每次发送文件的最大缓冲区是512字节,所以每次接收也是定义为512字节
byte[] buffer = new byte[];
int size = ;
//统计实际文件大小
long len = ;
//创建文件流,然后让文件流来根据路径创建一个文件
fs = new FileStream(fileName, FileMode.Append);
DateTime oTimeBegin = DateTime.Now;
//从终端不停的接受数据,然后写入文件里面,只到接受到的数据为0为止,则中断连接
while ((size = socketClient.Receive(buffer, , buffer.Length, SocketFlags.None)) > )
{
fs.Write(buffer, , size);
len += size;
}
DateTime oTimeEnd = DateTime.Now;
TimeSpan oTime = oTimeEnd.Subtract(oTimeBegin);
fs.Flush();
fs.Close(); socketClient.Shutdown(SocketShutdown.Both);
socketClient.Close();
Console.WriteLine("文件保存成功:" + fileName);
Console.WriteLine("接收文件用时:" + oTime.ToString() + ",文件大小:" + len / + "kb");
}
catch (Exception ex)
{
if (fs != null)
{
fs.Dispose();
}
if (File.Exists(fileName))
{
File.Delete(fileName);
}
Console.WriteLine(socketClient.RemoteEndPoint + "下线了"); break;
}
}
else
{ }
}
} public static void AcceptFile(string ip, int port, string fileName)
{
//创建服务端负责监听的套接字,参数(使用IPV4协议,使用流式连接,使用Tcp协议传输数据)
Socket socketListen = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socketListen.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
//获取Ip地址对象
IPAddress address = IPAddress.Parse(ip);
//创建包含Ip和port的网络节点对象
IPEndPoint endpoint = new IPEndPoint(address, port); //将负责监听的套接字绑定到唯一的Ip和端口上
socketListen.Bind(endpoint);
//设置监听队列的长度
socketListen.Listen();
connectDone.Set();
ObjectState state = new ObjectState(); //创建负责监听的线程,并传入监听方法
Thread threadWatch = new Thread(WatchConnecting);
state.fileName = fileName;
state.workSocket = socketListen;
state.workThread = threadWatch;
threadWatch.IsBackground = true;//设置为后台线程
threadWatch.Start(state);//开始线程 }
public static void CloseTcpSocket(Thread threadWatch, Socket socketWatch)
{ threadWatch.Abort();
socketWatch.Close();
Console.WriteLine("服务器关闭监听");
}
public static ManualResetEvent connectDone = new ManualResetEvent(false);
public static void FileMove(string ip, int port, string fromPath, string toPath)
{ AcceptFile(ip, port, toPath);
connectDone.WaitOne();
int i = SendFile(ip, port, fromPath, , );
Console.WriteLine("文件从" + fromPath + "到" + toPath + "移动成功!!!!");
} }
}
.调用代码
private void button1_Click(object sender, EventArgs e)
{
//string topath = $@"d:HQ.dat";
//string frompath = $@"e:\HQ.dat";
//Net.FileMove("127.0.0.1", 11000, frompath,topath);
string topath = $@"d:bb\HQ.dat";
string frompath = $@"d:aa\HQ.dat";
Net.FileMove("127.0.0.1", , frompath, topath);
}

Socket发送文件的更多相关文章

  1. android开发,socket发送文件,read阻塞,得不到文件尾-1

    这是我的接收文件代码:开始可以读取到-1,但是现在又读取不到了,所以才加上红色字解决的(注释的代码) File file = new File(mfilePath,"chetou." ...

  2. Python -- 网络编程 -- Socket发送文件

    客户端如果直接send两次,一次发文件名,一次发文件内容 服务端接受的时候会一起接收,不知怎么分开发送,或者分开接收, 或者全部接收再解析内容 今天发现传送mp3文件的时候没问题,传送文本文件的话,以 ...

  3. python 通过 socket 发送文件

    目录结构: client: #!/usr/bin/env python # -*-coding:utf-8 -*- import socket, struct, json download_dir = ...

  4. java socket 发送文件

    客户端: package tt; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStrea ...

  5. socket(TCP)发送文件

    一:由于在上一个随笔的基础之上拓展的所以直接上代码,客户端: using System; using System.Collections.Generic; using System.Componen ...

  6. C# socket 发送图片和文件

    先说服务端:界面:如图: 界面设计源码 namespace SocketJPGToTxt { partial class Form1 { /// <summary> /// 必需的设计器变 ...

  7. socket发送文字、图片、文件---基于python实现

    socket官方文档:https://docs.python.org/2/library/socket.html socket中文详细介绍:http://blog.csdn.net/rebelqsp/ ...

  8. C#使用FileSystemWatcher来监控指定文件夹,并使用TCP/IP协议通过Socket发送到另外指定文件夹

    项目需求: 局域网内有两台电脑,电脑A(Windows系统)主要是负责接收一些文件(远程桌面粘贴.FTP上传.文件夹共享等方式),希望能在A接收文件后自动传输到电脑B(Windows系统)来做一个备份 ...

  9. 利用Socket远程发送文件

    思想: 1.注意使用两个通道,一个普通对象通信通道,另一个纯净的文件字节流通道 2.利用通信通道发送文件请求,新建字节流通道,开始发送文件

随机推荐

  1. 【转】 python 删除非空文件夹

    转自:https://blog.csdn.net/xiaodongxiexie/article/details/77155864 一般删除文件时使用os库,然后利用os.remove(path)即可完 ...

  2. memsql 多节点部署

    以前部署使用的是docker,这个测试使用的是阿里云的机器 没有使用企业版,使用的是开发版,为一个master 多个Leaf 机器列表 172.31.128.165 172.31.128.166 17 ...

  3. Django 思维导图

  4. Java多线程编程核心技术,第四章

    1,ReentrantLock 2,object的wait(),wait(x),notify(),notifyAll(),分别等于Condition的await(),await(x,y),signal ...

  5. 字符串作为freemarker模板的简单实现例子

    本文转载自:http://blog.csdn.net/5iasp/article/details/27181365 package com.test.demo; import java.io.IOEx ...

  6. solr精确查询,查询关键字分词后,指定满足匹配所有

    一.solr查询,查询配置了查询分词器的字段,默认会对查询关键字做分词处理 1.如查询关键字F1501ZY000011,使用solr7自带的中文分词器,默认会分词为:f,1501,zy,000011 ...

  7. java selenium webdriver第四讲 应用小结

    部分api 1.访问网站 driver.get("http://www.baidu.com"); 或者 driver.navigate().to("http://www. ...

  8. python 爬预警没解析前的

  9. uwsgi配置文件的一些细节,uwsgi错误invalid request block size

    [uwsgi] #socket = #这种是使用代理方式访问的,不能直接输入端口访问,要搭配其他的HTTP服务比如NGINX,设置反向代理 http =: #这种是直接可以输入IP端口访问 modul ...

  10. python新里程

    为什么要学Python: 2018年6月开始自学Python.因为自己目前做Linux运维,感觉自己还需要掌握一门开发语言,在Java.python.php之间毫不犹豫的选择了Python,因为Pyt ...