您的位置:首页 > 编程语言 > C#

文件传输(C#)

2010-09-27 22:53 92 查看
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);

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: