当前位置: 首页 > news >正文

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 %
http://www.cnnetsun.cn/news/81839.html

相关文章:

  • Auto-Subtitle完整教程:5分钟学会为视频添加智能字幕
  • 5个简单步骤:掌握Visual Studio许可证到期日期的管理秘诀
  • 友达 G185XW01 V1 工业液晶显示屏:18.5 英寸宽温高响应场景的显示驱动技术解析
  • 正交实验设计在软件测试用例生成中的应用研究
  • 17、Unix Shell编程:临时文件、数据读写与环境变量详解
  • 校园实验室|基于springboot + vue校园实验室管理系统(源码+数据库+文档)
  • 25、深入探索Shell交互与非标准特性
  • Apache Mesos运维实战:集群管理完整指南与故障处理方案
  • FlutterFire Remote Config用户细分实战:精准触达不同用户群体
  • Python 开发 - Python 装饰器(装饰器概述、函数概念、装饰器手动实现、装饰器语法糖实现)
  • 太阳能电池串IV检测系统:精准契合行业标准,筑牢光伏质量防线
  • 64、Ubuntu 下 C/C++ 编程与 Mono 开发全解析
  • 5、Ubuntu系统网络与图形界面使用指南
  • 快速构建MCP工具的开发包FastMCP
  • 推荐字节的文档图像解析工具Dolphin
  • 查 Intel CPU 信息不用绕弯!这个专属查询工具,精准直达官网详情~
  • MediaCreationTool 报错?用 Rufus 一键制作 Windows 启动 U 盘,兼容 Win10/11!
  • Dify平台提示词调试功能提升AI输出质量实测
  • Java JDK下载+安装+配置环境(详细教程含图片),小白收藏这篇就够了
  • 前端性能优化之大文件上传,零基础入门到精通,收藏这篇就够了
  • 37、Windows 8 安全与诊断实用指南
  • 蛋白质丙酰化修饰在代谢调控与疾病研究中的进展与应用
  • C# + LiveCharts 工业监控界面,实时数据可视化实战
  • 在数字中国建设大潮中,科技管理部门如何借助靶向的知识产权智能运营平台解决客户流失率高,达成重塑差异化服务优势,最终重塑健全长效运营机制?
  • 如何确保服务器的安全性
  • 获取JD商品详情数据 get_item_pro
  • 提权学习之旅—Windows操作系统如何提升权限,网络安全零基础入门到精通实战教程!
  • Directus:重新定义企业数据管理的开源革命
  • RAX3000M刷机终极指南:从零开始玩转OpenWrt系统
  • 软件产品设计中用户体验提升的主要问题分析