zoukankan      html  css  js  c++  java
  • 如何通过Socket TCP发送并接收一个文件?

    一.小结

    1.大包发小包收,只发一次。

    2.发时把文件扩展名,文件长度也随同一起发送,方便接收端接收时另存为正确的文件类型,并判断是否已经接收完毕。

       如果不一起发送,分为文件扩展名,文件长度,文件内容,发送三次,在接收端,也可能会一起收到,反而不利于解析。

    二.客户发送端代码

            private void btnSend_Click(object sender, EventArgs e)
            {
                //组合出远程终结点  
                IPAddress ipAddress = IPAddress.Parse(this.txtIP3.Text);
                IPEndPoint hostEP = new IPEndPoint(ipAddress, Convert.ToInt32(this.txtPort3.Text));
                Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                try
                {
                    socket.Connect(hostEP);
    
                    //1.发送用户协议
                    string path1 = Environment.CurrentDirectory; //获取应用程序的当前工作目录。
                    string doc = "YourSendFile.pdf";
     string path = Path.Combine(path1, doc);
                    FileStream fs = File.Open(path, FileMode.Open);
    
                    //文件内容
                    byte[] bdata = new byte[fs.Length];
                    fs.Read(bdata, 0, bdata.Length);
                    fs.Close();
                    
                    //文件扩展名,固定3字节
                    byte[] fileExtArray = Encoding.UTF8.GetBytes(string.Format("{0:D3}", currentDocExt));
    
                    //文件长度, 固定为20字节,前面会自动补零
                    byte[] fileLengthArray = Encoding.UTF8.GetBytes(bdata.Length.ToString("D20"));
                    
                    //合并byte数组
                    byte[] fileArray = CombomBinaryArray(fileExtArray, fileLengthArray);
    
                    //合并byte数组
                    byte[] bdata1 = CombomBinaryArray(fileArray, bdata);
    
                    //发文件长度+文件内容
                    socket.Send(bdata1, bdata1.Length, 0);
    
                    //2.接收
                    //声明接收返回内容的字符串  
                    string recvStr = "";
    
                    //声明字节数组,一次接收数据的长度为 1024 字节  
                    byte[] recvBytes = new byte[1024];
    
                    //返回实际接收内容的字节数  
                    int bytes = 0;
    
                    //循环读取,直到接收完所有数据  
                    while (true)
                    {
                        bytes = socket.Receive(recvBytes, recvBytes.Length, 0);
                        //读取完成后退出循环  
                        if (bytes <= 0) break;
    
                        //将读取的字节数转换为字符串  
                        recvStr += Encoding.UTF8.GetString(recvBytes, 0, bytes);
                    }              
    
    
                    //禁用 Socket  
                    socket.Shutdown(SocketShutdown.Both);
    
                    //关闭 Socket  
                    socket.Close();
    
                    //... do some busness logic ...
    
                }
                catch (Exception e1)
                {
                    throw e1;
                }
            }

    三.服务接收端代码

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Net.Sockets;
    using System.Net;
    using System.Xml;
    using System.Configuration;
    using System.Windows.Forms;
    using System.IO;
    
    namespace ConsoleAppServer
    {
        class Program
        {
            [STAThread]
            static void Main(string[] args)
            {
                
                bool Done = false;
                IPAddress ipAddress = IPAddress.Parse(ConfigurationSettings.AppSettings["IP"].ToString());
                IPEndPoint hostEP = new IPEndPoint(ipAddress, Convert.ToInt32(ConfigurationSettings.AppSettings["Port"]));
                Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                socket.Bind(hostEP);
                socket.Listen(3);
                while (!Done)
                {
                    Console.WriteLine("waiting for client");
    
                    Socket client = socket.Accept();
    
                    Console.WriteLine("connected client");
    
                    //1.接收
                    //声明字节数组,一次接收数据的长度为 1024 字节  
                    byte[] recvBytes = new byte[1024];
                    //返回实际接收内容的字节数  
                    int bytes = 0;
                                    
                    int FileLength = 0; // 900866;
                    int ReceivedLength = 0;
    
                    //1.0 接收文件扩展名
                    bytes = client.Receive(recvBytes, 3, 0);
                    string fileExt = Encoding.UTF8.GetString(recvBytes, 0, bytes);
    
                    string vFilePath = Environment.CurrentDirectory;
                    string vFileName = vFilePath + "\Tmp" + Guid.NewGuid().ToString() + "." + fileExt;
    
                    //创建文件流,然后让文件流来根据路径创建一个文件
                    FileStream fs = new FileStream(vFileName, FileMode.Create);
    
                    //1.1 接收文件长度
                    bytes = client.Receive(recvBytes, 20, 0);
                    //将读取的字节数转换为字符串  
                    string fileLength = Encoding.UTF8.GetString(recvBytes, 0, bytes);
                    FileLength = Convert.ToInt32(fileLength);
    
                    //1.2接收文件内容
                    while (ReceivedLength < FileLength)
                    {
                        bytes = client.Receive(recvBytes, recvBytes.Length, 0);
                        ReceivedLength += bytes;
                        fs.Write(recvBytes, 0, bytes);
                    }
    
                    fs.Flush();
                    fs.Close();
    
    
                    //... do some business logic ...   
                   string returnData = SomeBusinessLogic();
    
                    //2.发送
                    byte[] bdata = Encoding.UTF8.GetBytes(returnData);
                    client.Send(bdata, bdata.Length, 0);
    
                    client.Close();
                }
    
                socket.Shutdown(SocketShutdown.Both);
                socket.Close();
            }
            
        }
    }
  • 相关阅读:
    【Uvalive4960】 Sensor network (苗条树,进化版)
    【UVA 1151】 Buy or Build (有某些特别的东东的最小生成树)
    【UVA 1395】 Slim Span (苗条树)
    【UVA 10600】 ACM Contest and Blackout(最小生成树和次小生成树)
    【UVA 10369】 Arctic Network (最小生成树)
    【UVA 10816】 Travel in Desert (最小瓶颈树+最短路)
    【UVA 11183】 Teen Girl Squad (定根MDST)
    【UVA 11865】 Stream My Contest (二分+MDST最小树形图)
    【UVA 11354】 Bond (最小瓶颈生成树、树上倍增)
    【LA 5713 】 Qin Shi Huang's National Road System (MST)
  • 原文地址:https://www.cnblogs.com/liuzhendong/p/4502621.html
Copyright © 2011-2022 走看看