jinyuttt

导航

c# 文件传输

突然想起以前做的文件传输没有资料了,自己写的也不知道哪里去了,一下把网上的代码贴到我这里,有待研究。

第一类:点对点传输客户端 using System; using System.Collections.Generic;

using System.ComponentModel;

using System.Data; using System.Drawing;

 using System.Text;

using System.Windows.Forms;

 using System.Net; using System.Threading;

 using System.Net.Sockets;

using System.IO;

namespace TestSocketServerHSTF {

public partial class Form1 : Form {

public Form1() {

 InitializeComponent(); //不显示出dataGridView1的最后一行空白

 dataGridView1.AllowUserToAddRows = false; }

 #region 定义变量 #endregion #region 进入窗体即启动服务

private void Form1_Load(object sender, EventArgs e)

{ //开启接收线程

Thread TempThread = new Thread(new ThreadStart(this.StartReceive));

 TempThread.Start(); }

#endregion #region 功能函数

private void StartReceive()

{ //创建一个网络端点

IPEndPoint ipep = new IPEndPoint(IPAddress.Any, int.Parse("2005"));

//MessageBox.Show(IPAddress.Any);

//创建一个套接字

Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //绑定套接字到端口

server.Bind(ipep); //开始侦听(并堵塞该线程)

 server.Listen(10); //确认连接

 Socket client = server.Accept(); //获得客户端节点对象

 IPEndPoint clientep = (IPEndPoint)client.RemoteEndPoint; //获得[文件名]

string SendFileName = System.Text.Encoding.Unicode.GetString(TransferFiles.ReceiveVarData(client));

//MessageBox.Show("文件名" + SendFileName);

//获得[包的大小] s

tring bagSize = System.Text.Encoding.Unicode.GetString(TransferFiles.ReceiveVarData(client));

//MessageBox.Show("包大小" + bagSize);

//获得[包的总数量]

int bagCount = int.Parse(System.Text.Encoding.Unicode.GetString(TransferFiles.ReceiveVarData(client)));

//MessageBox.Show("包的总数量" + bagCount);

 //获得[最后一个包的大小]

string bagLast = System.Text.Encoding.Unicode.GetString(TransferFiles.ReceiveVarData(client));

//MessageBox.Show("最后一个包的大小" + bagLast);

//创建一个新文件

FileStream MyFileStream = new FileStream(SendFileName, FileMode.Create, FileAccess.Write);

 //已发送包的个数

 int SendedCount = 0;

while (true) { byte[] data = TransferFiles.ReceiveVarData(client);

 if (data.Length == 0) { break; }

else { SendedCount++;

//将接收到的数据包写入到文件流对象

 MyFileStream.Write(data, 0, data.Length);

//显示已发送包的个数

//MessageBox.Show("已发送包个数"+SendedCount.ToString()); } }

//关闭文件流 MyFileStream.Close();

//关闭套接字 client.Close();

//填加到dgv里 //文件大小,IP,已发送包的个数,文件名,包的总量,最后一个包的大小

 this.dataGridView1.Rows.Add(bagSize, clientep.Address, SendedCount, SendFileName, bagCount, bagLast);

 //MessageBox.Show("文件接收完毕!"); }

 #endregion

第二类: #region 拦截Windows消息,关闭窗体时执行

 protected override void WndProc(ref Message m) {

 const int WM_SYSCOMMAND = 0x0112; const int SC_CLOSE = 0xF060;

 if (m.Msg == WM_SYSCOMMAND && (int)m.WParam == SC_CLOSE)

{//捕捉关闭窗体消息

// User clicked close button

//this.WindowState = FormWindowState.Minimized;//把右上角红叉关闭按钮变最小化

 ServiceStop(); } base.WndProc(ref m); }

#endregion #region 停止服务

 //停止服务

private void ServiceStop() { try { } catch { } try { } catch { } } #endregion } 服务端 ////////////////////////////Begin-公共模块////////////////////////////////////// using System;

 using System.Collections.Generic;

using System.Text; using System.Net;

using System.Net.Sockets;

using System.Windows.Forms; namespace TestSocketServerHSTF { class TransferFiles { public TransferFiles() {

// // TODO: 在此处添加构造函数逻辑 // }

 public static int SendData(Socket s, byte[] data)

{ int total = 0; int size = data.Length; int dataleft = size; int sent;

while (total < size) {

  sent = s.Send(data, total, dataleft, SocketFlags.None); total += sent; dataleft -= sent;

}

 return total;

}

public static byte[] ReceiveData(Socket s, int size)

{

int total = 0; int dataleft = size; byte[] data = new byte[size]; int recv;

while (total < size) {

 recv = s.Receive(data, total, dataleft, SocketFlags.None);

if (recv == 0) { data = null; break; }

total += recv; dataleft -= recv;

}

 return data;

 }

 public static int SendVarData(Socket s, byte[] data) {

 int total = 0; int size = data.Length; int dataleft = size; int sent;

byte[] datasize = new byte[4]; datasize = BitConverter.GetBytes(size);

sent = s.Send(datasize);

while (total < size) {

sent = s.Send(data, total, dataleft, SocketFlags.None);

total += sent; dataleft -= sent;

} return total;

}

public static byte[] ReceiveVarData(Socket s) {

 int total = 0; int recv; byte[] datasize = new byte[4];

recv = s.Receive(datasize, 0, 4, SocketFlags.None);

int size = BitConverter.ToInt32(datasize, 0); int dataleft = size;

 byte[] data = new byte[size];

while (total < size) {

 recv = s.Receive(data, total, dataleft, SocketFlags.None);

if (recv == 0) { data = null; break; }

 total += recv; dataleft -= recv;

}

return data;

} } } } /////////////////////////////End-公共模块///////////////////////////////////////

第二类:套接字

 using System;

 using System.Net;

using System.Net.Sockets;

 using System.IO;

namespace Win {

////// Net : 提供静态方法,对常用的网络操作进行封装 ///

public sealed class Net { private Net() { } ////// 连接使用 tcp 协议的服务端 //////服务端的ip地址///服务端的端口号///

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; } ////// 用主机名称连接使用Tcp协议的服务端 //////在hosts 文件中存在的主机名称///服务端的端口号///

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; } ////// 向远程主机发送数据 //////要发送数据且已经连接到远程主机的 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 == 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; } ////// 向远程主机发送数据 //////要发送数据且已经连接到远程主机的 Socket///待发送的字符串///发送数据的超时时间,以秒为单位,可以精确到微秒///0:发送数据成功;-1:超时;-2:发送数据出现错误;-3:发送数据时出现异常 ////// 当 outTime 指定为-1时,将一直等待直到有数据需要发送 ///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)); } ////// 接收远程主机发送的数据 //////要接收数据且已经连接到远程主机的 socket///接收数据的缓冲区///接收数据的超时时间,以秒为单位,可以精确到微秒///0:接收数据成功;-1:超时;-2:接收数据出现错误;-3:接收数据时出现异常 ////// 1、当 outTime 指定为-1时,将一直等待直到有数据需要接收; /// 2、需要接收的数据的长度,由 buffer 的长度决定。 ///

 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;

 } ////// 接收远程主机发送的数据 //////要接收数据且已经连接到远程主机的 socket///存储接收到的数据的字符串///待接收的数据的长度///接收数据的超时时间,以秒为单位,可以精确到微秒///0:接收数据成功;-1:超时;-2:接收数据出现错误;-3:接收数据时出现异常 ////// 当 outTime 指定为-1时,将一直等待直到有数据需要接收; ///

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; } ////// 向远程主机发送文件 //////要发送数据且已经连接到远程主机的 socket///待发送的文件名称///文件发送时的缓冲区大小///发送缓冲区中的数据的超时时间///0:发送文件成功;-1:超时;-2:发送文件出现错误;-3:发送文件出现异常;-4:读取待发送文件发生错误 ////// 当 outTime 指定为-1时,将一直等待直到有数据需要发送 ///

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; } ////// 向远程主机发送文件 //////要发送数据且已经连接到远程主机的 socket///待发送的文件名称///0:发送文件成功;-1:超时;-2:发送文件出现错误;-3:发送文件出现异常;-4:读取待发送文件发生错误 p

ublic static int SendFile(Socket socket, string fileName)

{

 return SendFile(socket, fileName, 2048, 1);

} ////// 接收远程主机发送的文件 //////待接收数据且已经连接到远程主机的 socket///保存接收到的数据的文件名///待接收的文件的长度///接收文件时最大的缓冲区大小///接受缓冲区数据的超时时间///0:接收文件成功;-1:超时;-2:接收文件出现错误;-3:接收文件出现异常;-4:写入接收文件发生错误 ////// 当 outTime 指定为-1时,将一直等待直到有数据需要接收 ///

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; } ////// 接收远程主机发送的文件 //////待接收数据且已经连接到远程主机的 socket///保存接收到的数据的文件名///待接收的文件的长度///0:接收文件成功;-1:超时;-2:接收文件出现错误;-3:接收文件出现异常;-4:写入接收文件发生错误

 public static int RecvFile(Socket socket, string fileName, long fileLength)

{ return RecvFile(socket, fileName, fileLength, 2048, 1); }

 }

}

posted on 2010-12-03 10:58  代码苦行僧  阅读(2289)  评论(2编辑  收藏  举报