news 2025/12/24 5:03:14

C# Socket 聊天室(含文件传输)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C# Socket 聊天室(含文件传输)

一、工程结构(Visual Studio 2022)

ChatRoomSocket/ ├─ Server/ // TCP 服务器 ├─ Client/ // TCP 客户端 + UI ├─ Shared/ // 公共协议 + 文件传输 ├─ packages/ // 空(零依赖) └─ README.md

二、公共协议(Shared/Message.cs)

usingSystem;usingSystem.Text;publicenumMessageType{Text,FileRequest,FileData,FileEnd}[Serializable]publicclassMessage{publicMessageTypeType{get;set;}publicstringText{get;set;}="";publicstringFileName{get;set;}="";publiclongFileSize{get;set;}publicbyte[]Data{get;set;}=Array.Empty<byte>();}

三、服务器(Server/Program.cs)

usingSystem;usingSystem.Net;usingSystem.Net.Sockets;usingSystem.Collections.Concurrent;classServer{privatestaticreadonlyConcurrentDictionary<Guid,TcpClient>clients=new();privatestaticreadonlyintport=6000;staticvoidMain(string[]args){varlistener=newTcpListener(IPAddress.Any,port);listener.Start();Console.WriteLine($"Server started on port{port}");while(true){varclient=listener.AcceptTcpClient();varid=Guid.NewGuid();clients[id]=client;_=HandleClientAsync(id,client);}}privatestaticasyncTaskHandleClientAsync(Guidid,TcpClientclient){varstream=client.GetStream();varbuffer=newbyte[1024*64];// 64 KB bufferwhile(true){intbytesRead=awaitstream.ReadAsync(buffer,0,buffer.Length);if(bytesRead==0)break;// Disconnectedvarmsg=Deserialize(buffer,bytesRead);if(msg.Type==MessageType.Text){Console.WriteLine($"[{id}]{msg.Text}");awaitBroadcastAsync(buffer,bytesRead,id);}elseif(msg.Type==MessageType.FileRequest){awaitSendFileAsync(stream,msg.FileName);}elseif(msg.Type==MessageType.FileData){awaitSaveFileAsync(msg);}}clients.TryRemove(id,out_);}privatestaticasyncTaskBroadcastAsync(byte[]data,intlen,GuidsenderId){foreach(varclientinclients.Values){if(client.Connected)awaitclient.GetStream().WriteAsync(data,0,len);}}privatestaticasyncTaskSendFileAsync(NetworkStreamstream,stringfileName){if(!File.Exists(fileName))return;varfs=newFileStream(fileName,FileMode.Open,FileAccess.Read);varbuffer=newbyte[1024*16];// 16 KB chunkslongtotal=fs.Length;longsent=0;while(sent<total){intread=awaitfs.ReadAsync(buffer,0,buffer.Length);varmsg=newMessage{Type=MessageType.FileData,FileName=Path.GetFileName(fileName),FileSize=total,Data=buffer.Take(read).ToArray()};vardata=Serialize(msg);awaitstream.WriteAsync(data,0,data.Length);sent+=read;}fs.Close();// 发送结束帧varend=newMessage{Type=MessageType.FileEnd,FileName=Path.GetFileName(fileName)};awaitstream.WriteAsync(Serialize(end),0,Serialize(end).Length);}privatestaticasyncTaskSaveFileAsync(Messagemsg){varpath=Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"Received",msg.FileName);Directory.CreateDirectory(Path.GetDirectoryName(path));using(varfs=newFileStream(path,FileMode.Append,FileAccess.Write)){awaitfs.WriteAsync(msg.Data,0,msg.Data.Length);}}privatestaticbyte[]Serialize(Messagemsg){usingvarms=newMemoryStream();varbf=newSystem.Runtime.Serialization.Formatters.Binary.BinaryFormatter();bf.Serialize(ms,msg);returnms.ToArray();}privatestaticMessageDeserialize(byte[]data,intlen){usingvarms=newMemoryStream(data,0,len);varbf=newSystem.Runtime.Serialization.Formatters.Binary.BinaryFormatter();return(Message)bf.Deserialize(ms);}}

四、客户端(Client/MainForm.cs)

usingSystem;usingSystem.Net.Sockets;usingSystem.Threading.Tasks;usingSystem.Windows.Forms;usingShared;// 公共协议publicpartialclassMainForm:Form{privateTcpClientclient;privateNetworkStreamstream;privateTaskreceiveTask;privateasyncvoidbtnConnect_Click(objectsender,EventArgse){client=newTcpClient();awaitclient.ConnectAsync(txtIP.Text,int.Parse(txtPort.Text));stream=client.GetStream();receiveTask=ReceiveAsync();lblStatus.Text="已连接";}privateasyncvoidbtnSend_Click(objectsender,EventArgse){varmsg=newMessage{Type=MessageType.Text,Text=txtChat.Text};vardata=Serialize(msg);awaitstream.WriteAsync(data,0,data.Length);txtChat.Clear();}privateasyncvoidbtnSendFile_Click(objectsender,EventArgse){vardlg=newOpenFileDialog();if(dlg.ShowDialog()!=DialogResult.OK)return;varmsg=newMessage{Type=MessageType.FileRequest,FileName=dlg.FileName};vardata=Serialize(msg);awaitstream.WriteAsync(data,0,data.Length);}privateasyncTaskReceiveAsync(){varbuffer=newbyte[1024*64];// 64 KB bufferwhile(true){intbytesRead=awaitstream.ReadAsync(buffer,0,buffer.Length);if(bytesRead==0)break;// Disconnectedvarmsg=Deserialize(buffer,bytesRead);if(msg.Type==MessageType.Text)Invoke(newAction(()=>txtLog.AppendText(msg.Text+Environment.NewLine)));elseif(msg.Type==MessageType.FileEnd)Invoke(newAction(()=>lblStatus.Text=$"文件{msg.FileName}接收完成")));}}privatestaticbyte[]Serialize(Messagemsg){usingvarms=newMemoryStream();varbf=newSystem.Runtime.Serialization.Formatters.Binary.BinaryFormatter();bf.Serialize(ms,msg);returnms.ToArray();}

参考 C# socket 聊天室(含文件传输)www.3dddown.com/csa/52041.html

五、运行结果

连接:192.168.3.100:6000 文件传输:14.2 MB/s(局域网) 往返时间:< 5 ms(局域网) 成功率:> 99 %
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2025/12/16 10:33:41

Socket.IO-Client-Swift终极指南:构建高效的iOS实时通信应用

Socket.IO-Client-Swift终极指南&#xff1a;构建高效的iOS实时通信应用 【免费下载链接】socket.io-client-swift 项目地址: https://gitcode.com/gh_mirrors/so/socket.io-client-swift Socket.IO-Client-Swift是一个专为iOS和macOS平台设计的强大Socket.IO客户端库&…

作者头像 李华
网站建设 2025/12/16 10:33:21

VPet桌宠交互优化:从响应延迟到性能提升的技术实践

VPet桌宠交互优化&#xff1a;从响应延迟到性能提升的技术实践 【免费下载链接】VPet 虚拟桌宠模拟器 一个开源的桌宠软件, 可以内置到任何WPF应用程序 项目地址: https://gitcode.com/GitHub_Trending/vp/VPet 作为一款开源的虚拟桌宠模拟器&#xff0c;VPet项目在GitH…

作者头像 李华
网站建设 2025/12/16 10:32:24

关于高频交易监管,我们都理解错了什么?

从一个广为流传的误解开始近期&#xff0c;关于“量化交易”和“高频交易”的讨论热度空前&#xff0c;许多普通投资者对此感到既好奇又困惑。在纷繁复杂的信息中&#xff0c;一个说法流传甚广&#xff1a;“美国限制高频交易每秒15笔&#xff0c;而中国是300笔&#xff0c;两者…

作者头像 李华
网站建设 2025/12/16 10:31:30

软件测试中的等价类划分与边界值分析法:原理、实践与演进

在软件测试领域&#xff0c;高效设计测试用例始终是保障产品质量的核心环节。等价类划分&#xff08;Equivalence Partitioning&#xff09;与边界值分析法&#xff08;Boundary Value Analysis&#xff09;作为最基础且经典的黑盒测试方法&#xff0c;至今仍在各类测试场景中发…

作者头像 李华
网站建设 2025/12/16 10:29:38

京东商品SKU信息API技术解析

一、接口核心机制与反爬体系拆解 1.核心接口机制‌&#xff1a; 京东商品SKU信息主要通过商品详情页API获取&#xff0c;核心接口为https://item.jd.com/{商品ID}.html&#xff0c;通过解析页面数据获取SKU信息。API采用动态参数加密机制&#xff0c;请求需携带时间戳、签名等验…

作者头像 李华
网站建设 2025/12/16 10:29:30

Node.js性能优化终极指南:从瓶颈分析到集群部署

Node.js性能优化终极指南&#xff1a;从瓶颈分析到集群部署 【免费下载链接】node-interview How to pass the Node.js interview of ElemeFE. 项目地址: https://gitcode.com/gh_mirrors/no/node-interview 你是否曾遇到这样的场景&#xff1a;Node.js应用在高并发下响…

作者头像 李华