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

     }

    }

  • 相关阅读:
    react学习总结(一)
    jQuery的attr()与prop()的区别
    Vue.js学习(常用指令)
    Node.js学习(篇章一)
    CSS3关于-webkit-tap-highlight-color属性
    position布局影响点击事件以及冒泡获取事件目标
    取消事件默认行为(移动端)
    rem与px之间的换算(移动端)
    Node.js(初识)
    ES6(变量的解构赋值)
  • 原文地址:https://www.cnblogs.com/jinyuttt/p/1895251.html
Copyright © 2020-2023  润新知