如何通过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(); } } }
作者:BobLiu
邮箱:lzd_ren@hotmail.com
出处:http://www.cnblogs.com/liuzhendong
本文版权归作者所有,欢迎转载,未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
邮箱:lzd_ren@hotmail.com
出处:http://www.cnblogs.com/liuzhendong
本文版权归作者所有,欢迎转载,未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
分类:
.Net, C#, Asp.net
, Socket TCP
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构