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); }
}
}