文件传输(C#)
Posted mb630ec035bcfe8
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了文件传输(C#)相关的知识,希望对你有一定的参考价值。
using System;
using System.Net;
using System.Net.Sockets;
using System.IO;
namespace Win
/// <summary>
/// Net : 提供静态方法,对常用的网络操作进行封装
/// </summary>
public sealed class Net
private Net()
/// <summary>
/// 连接使用 tcp 协议的服务端
/// </summary>
/// <param name="ip">服务端的ip地址</param>
/// <param name="port">服务端的端口号</param>
/// <returns></returns>
public static Socket ConnectServer(string ip, int port)
Socket s = null;
try
IPAddress ipAddress = IPAddress.Parse(ip);
IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, port);
s = new Socket(ipEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
s.Connect(ipEndPoint);
if (s.Connected == false)
s = null;
catch (Exception e)
Log.WriteLog(e);
return s;
/// <summary>
/// 用主机名称连接使用Tcp协议的服务端
/// </summary>
/// <param name="hostName">在hosts 文件中存在的主机名称</param>
/// <param name="port">服务端的端口号</param>
/// <returns></returns>
public static Socket ConnectServByHostName(string hostName, int port)
Socket s = null;
IPHostEntry iphe = null;
try
iphe = Dns.Resolve(hostName);
foreach (IPAddress ipad in iphe.AddressList)
IPEndPoint ipe = new IPEndPoint(ipad, port);
Socket tmps = new Socket(ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
tmps.Connect(ipe);
if (tmps.Connected)
s = tmps;
break;
else
continue;
catch (Exception e)
Log.WriteLog(e);
return s;
/// <summary>
/// 向远程主机发送数据
/// </summary>
/// <param name="socket">要发送数据且已经连接到远程主机的 Socket</param>
/// <param name="buffer">待发送的数据</param>
/// <param name="outTime">发送数据的超时时间,以秒为单位,可以精确到微秒</param>
/// <returns>0:发送数据成功;-1:超时;-2:发送数据出现错误;-3:发送数据时出现异常</returns>
/// <remarks >
/// 当 outTime 指定为-1时,将一直等待直到有数据需要发送
/// </remarks>
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 == 0)
throw new ArgumentException("参数buffer 为null ,或者长度为 0");
int flag = 0;
try
int left = buffer.Length;
int sndLen = 0;
while (true)
if ((socket.Poll(outTime * 1000000, SelectMode.SelectWrite) == true))
// 收集了足够多的传出数据后开始发送
sndLen = socket.Send(buffer, sndLen, left, SocketFlags.None);
left -= sndLen;
if (left == 0)
// 数据已经全部发送
flag = 0;
break;
else
if (sndLen > 0)
// 数据部分已经被发送
continue;
else
// 发送数据发生错误
flag = -2;
break;
else
// 超时退出
flag = -1;
break;
catch (SocketException e)
Log.WriteLog(e);
flag = -3;
return flag;
/// <summary>
/// 向远程主机发送数据
/// </summary>
/// <param name="socket">要发送数据且已经连接到远程主机的 Socket</param>
/// <param name="buffer">待发送的字符串</param>
/// <param name="outTime">发送数据的超时时间,以秒为单位,可以精确到微秒</param>
/// <returns>0:发送数据成功;-1:超时;-2:发送数据出现错误;-3:发送数据时出现异常</returns>
/// <remarks >
/// 当 outTime 指定为-1时,将一直等待直到有数据需要发送
/// </remarks>
public static int SendData(Socket socket, string buffer, int outTime)
if (buffer == null || buffer.Length == 0)
throw new ArgumentException("待发送的字符串长度不能为零.");
return (SendData(socket, System.Text.Encoding.Default.GetBytes(buffer), outTime));
/// <summary>
/// 接收远程主机发送的数据
/// </summary>
/// <param name="socket">要接收数据且已经连接到远程主机的 socket</param>
/// <param name="buffer">接收数据的缓冲区</param>
/// <param name="outTime">接收数据的超时时间,以秒为单位,可以精确到微秒</param>
/// <returns>0:接收数据成功;-1:超时;-2:接收数据出现错误;-3:接收数据时出现异常</returns>
/// <remarks >
/// 1、当 outTime 指定为-1时,将一直等待直到有数据需要接收;
/// 2、需要接收的数据的长度,由 buffer 的长度决定。
/// </remarks>
public static int RecvData(Socket socket, byte[] buffer, int outTime)
if (socket == null || socket.Connected == false)
throw new ArgumentException("参数socket 为null,或者未连接到远程计算机");
if (buffer == null || buffer.Length == 0)
throw new ArgumentException("参数buffer 为null ,或者长度为 0");
buffer.Initialize();
int left = buffer.Length;
int curRcv = 0;
int flag = 0;
try
while (true)
if (socket.Poll(outTime * 1000000, SelectMode.SelectRead))
// 已经有数据等待接收
curRcv = socket.Receive(buffer, curRcv, left, SocketFlags.None);
left -= curRcv;
if (left == 0)
// 数据已经全部接收
flag = 0;
break;
else
if (curRcv > 0)
// 数据已经部分接收
continue;
else
// 出现错误
flag = -2;
break;
else
// 超时退出
flag = -1;
break;
catch (SocketException e)
Log.WriteLog(e);
flag = -3;
return flag;
/// <summary>
/// 接收远程主机发送的数据
/// </summary>
/// <param name="socket">要接收数据且已经连接到远程主机的 socket</param>
/// <param name="buffer">存储接收到的数据的字符串</param>
/// <param name="bufferLen">待接收的数据的长度</param>
/// <param name="outTime">接收数据的超时时间,以秒为单位,可以精确到微秒</param>
/// <returns>0:接收数据成功;-1:超时;-2:接收数据出现错误;-3:接收数据时出现异常</returns>
/// <remarks >
/// 当 outTime 指定为-1时,将一直等待直到有数据需要接收;
/// </remarks>
public static int RecvData(Socket socket, string buffer, int bufferLen, int outTime)
if (bufferLen <= 0)
throw new ArgumentException("存储待接收数据的缓冲区长度必须大于0");
byte[] tmp = new byte[bufferLen];
int flag = 0;
if ((flag = RecvData(socket, tmp, outTime)) == 0)
buffer = System.Text.Encoding.Default.GetString(tmp);
return flag;
/// <summary>
/// 向远程主机发送文件
/// </summary>
/// <param name="socket" >要发送数据且已经连接到远程主机的 socket</param>
/// <param name="fileName">待发送的文件名称</param>
/// <param name="maxBufferLength">文件发送时的缓冲区大小</param>
/// <param name="outTime">发送缓冲区中的数据的超时时间</param>
/// <returns>0:发送文件成功;-1:超时;-2:发送文件出现错误;-3:发送文件出现异常;-4:读取待发送文件发生错误</returns>
/// <remarks >
/// 当 outTime 指定为-1时,将一直等待直到有数据需要发送
/// </remarks>
public static int SendFile(Socket socket, string fileName, int maxBufferLength, int outTime)
if (fileName == null || maxBufferLength <= 0)
throw new ArgumentException("待发送的文件名称为空或发送缓冲区的大小设置不正确.");
int flag = 0;
try
FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
long fileLen = fs.Length; // 文件长度
long leftLen = fileLen; // 未读取部分
int readLen = 0; // 已读取部分
byte[] buffer = null;
if (fileLen <= maxBufferLength)
/* 文件可以一次读取*/
buffer = new byte[fileLen];
readLen = fs.Read(buffer, 0, (int)fileLen);
flag = SendData(socket, buffer, outTime);
else
/* 循环读取文件,并发送 */
buffer = new byte[maxBufferLength];
while (leftLen != 0)
readLen = fs.Read(buffer, 0, maxBufferLength);
if ((flag = SendData(socket, buffer, outTime)) < 0)
break;
leftLen -= readLen;
fs.Close();
catch (IOException e)
Log.WriteLog(e);
flag = -4;
return flag;
/// <summary>
/// 向远程主机发送文件
/// </summary>
/// <param name="socket" >要发送数据且已经连接到远程主机的 socket</param>
/// <param name="fileName">待发送的文件名称</param>
/// <returns>0:发送文件成功;-1:超时;-2:发送文件出现错误;-3:发送文件出现异常;-4:读取待发送文件发生错误</returns>
public static int SendFile(Socket socket, string fileName)
return SendFile(socket, fileName, 2048, 1);
/// <summary>
/// 接收远程主机发送的文件
/// </summary>
/// <param name="socket">待接收数据且已经连接到远程主机的 socket</param>
/// <param name="fileName">保存接收到的数据的文件名</param>
/// <param name="fileLength" >待接收的文件的长度</param>
/// <param name="maxBufferLength">接收文件时最大的缓冲区大小</param>
/// <param name="outTime">接受缓冲区数据的超时时间</param>
/// <returns>0:接收文件成功;-1:超时;-2:接收文件出现错误;-3:接收文件出现异常;-4:写入接收文件发生错误</returns>
/// <remarks >
/// 当 outTime 指定为-1时,将一直等待直到有数据需要接收
/// </remarks>
public static int RecvFile(Socket socket, string fileName, long fileLength, int maxBufferLength, int outTime)
if (fileName == null || maxBufferLength <= 0)
throw new ArgumentException("保存接收数据的文件名称为空或发送缓冲区的大小设置不正确.");
int flag = 0;
try
FileStream fs = new FileStream(fileName, FileMode.Create);
byte[] buffer = null;
if (fileLength <= maxBufferLength)
/* 一次读取所传送的文件 */
buffer = new byte[fileLength];
if ((flag = RecvData(socket, buffer, outTime)) == 0)
fs.Write(buffer, 0, (int)fileLength);
else
/* 循环读取网络数据,并写入文件 */
int rcvLen = maxBufferLength;
long leftLen = fileLength; //剩下未写入的数据
buffer = new byte[rcvLen];
while (leftLen != 0)
if ((flag = RecvData(socket, buffer, outTime)) < 0)
break;
fs.Write(buffer, 0, rcvLen);
leftLen -= rcvLen;
rcvLen = (maxBufferLength < leftLen) ? maxBufferLength : ((int)leftLen);
fs.Close();
catch (IOException e)
Log.WriteLog(e);
flag = -4;
return flag;
/// <summary>
/// 接收远程主机发送的文件
/// </summary>
/// <param name="socket">待接收数据且已经连接到远程主机的 socket</param>
/// <param name="fileName">保存接收到的数据的文件名</param>
/// <param name="fileLength" >待接收的文件的长度</param>
/// <returns>0:接收文件成功;-1:超时;-2:接收文件出现错误;-3:接收文件出现异常;-4:写入接收文件发生错误</returns>
public static int RecvFile(Socket socket, string fileName, long fileLength)
return RecvFile(socket, fileName, fileLength, 2048, 1);
以上是关于文件传输(C#)的主要内容,如果未能解决你的问题,请参考以下文章
在 C# 中使用 WinSCP 传输仅包含数字而不包含字母的文件?