news 2026/3/10 16:16:31

手搓C#网络通信:从心跳包到群聊室的实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
手搓C#网络通信:从心跳包到群聊室的实现

1、C#Socket异步、同步通信服务端、客户端源码; 2、断线重连(服务端或客户端没有启动顺序要求,先开启的等待另一端连接);3、服务端支持同时连接多个客户端;4、阅读代码就明白通信道理,注释详细; 5、VS2015编译通过。

咱们直接进入正题,先看服务端代码。这个服务端用了异步处理,能同时接客多个客户端。注意看这个魔法方法BeginAccept,它像极了餐馆里的自动叫号机:

// 服务端核心代码(异步版) public class AsyncServer { private Socket _serverSocket; private List<Socket> _clientSockets = new List<Socket>(); // 客户池 public void Start(int port) { _serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _serverSocket.Bind(new IPEndPoint(IPAddress.Any, port)); _serverSocket.Listen(10); Console.WriteLine("服务端已启动,进入贤者模式..."); // 开始等待客人上门(非阻塞) _serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), null); } private void AcceptCallback(IAsyncResult ar) { Socket client = _serverSocket.EndAccept(ar); _clientSockets.Add(client); Console.WriteLine($"新客户上线,当前在线:{_clientSockets.Count}"); // 给新客户配专属服务员 byte[] buffer = new byte[1024]; client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), new ClientState { Socket = client, Buffer = buffer }); // 继续蹲点等新客 _serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), null); } }

重点来了:BeginAccept是异步接客的关键,不会阻塞主线程。每个新连接进来都会触发AcceptCallback,这里用了递归式等待——处理完一个立即准备接待下一个。

客户端的重连机制像个倔强的追求者,核心代码如下:

// 客户端重连模块 public class ReconnectClient { private Socket _clientSocket; private Timer _reconnectTimer; public void Connect(string ip, int port) { _clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // 开启死亡循环模式尝试连接 _reconnectTimer = new Timer(state => { try { _clientSocket.Connect(ip, port); Console.WriteLine("成功勾搭上服务端!"); StartReceiving(); // 开始接收数据 _reconnectTimer.Dispose(); // 关掉定时器 } catch { Console.WriteLine("服务端不在线,5秒后继续撩..."); } }, null, 0, 5000); // 每5秒尝试一次 } }

这个Timer相当于备胎定时器,每隔5秒就尝试连接,直到成功为止。注意finally里没有直接关闭socket,保持长连接状态。

再看数据接收的骚操作,用状态对象保存会话:

// 接收数据时的回调处理 private void ReceiveCallback(IAsyncResult ar) { ClientState state = (ClientState)ar.AsyncState; try { int bytesRead = state.Socket.EndReceive(ar); if (bytesRead > 0) { string msg = Encoding.UTF8.GetString(state.Buffer, 0, bytesRead); Console.WriteLine($"收到情报:{msg}"); // 继续监听下一波数据(像接龙游戏) state.Socket.BeginReceive(state.Buffer, 0, state.Buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), state); } } catch (SocketException ex) { Console.WriteLine($"客户失联,错误码:{ex.SocketErrorCode}"); state.Socket.Close(); _clientSockets.Remove(state.Socket); // 从客户池踢出 } } // 会话状态封装类 public class ClientState { public Socket Socket { get; set; } public byte[] Buffer { get; set; } }

这里用了ClientState对象来保存socket和buffer,避免闭包问题。异常处理中特别关注SocketException,能准确识别网络断开等状况。

1、C#Socket异步、同步通信服务端、客户端源码; 2、断线重连(服务端或客户端没有启动顺序要求,先开启的等待另一端连接);3、服务端支持同时连接多个客户端;4、阅读代码就明白通信道理,注释详细; 5、VS2015编译通过。

群发消息的实现像极了小区广播:

// 服务端广播功能 public void Broadcast(string message) { byte[] data = Encoding.UTF8.GetBytes(message); foreach (var client in _clientSockets.ToArray()) // ToArray防止遍历时集合被修改 { if (client.Connected) { client.BeginSend(data, 0, data.Length, SocketFlags.None, new AsyncCallback(SendCallback), client); } else { _clientSockets.Remove(client); // 清理僵尸连接 } } }

这里用了ToArray来遍历副本,避免在迭代时修改集合导致的异常。BeginSend的异步发送不会阻塞服务端,适合高并发场景。

在VS2015中编译时要注意:项目属性→生成→目标框架要选.NET 4.5以上,确保Socket异步API可用。如果遇到SocketException 10054错误,那是客户端异常断线的正常反馈,咱们已经在接收回调里处理了。

最后来个心跳包检测存活的小技巧:

// 心跳检测 private void StartHeartbeat() { Timer heartbeatTimer = new Timer(state => { foreach (var client in _clientSockets.ToArray()) { if (!client.Poll(1000, SelectMode.SelectRead)) // 检测连接状态 { Console.WriteLine("检测到僵尸连接,执行清理"); client.Close(); _clientSockets.Remove(client); } } }, null, 60000, 60000); // 每分钟检测一次 }

Poll方法能准确判断TCP连接的实际状态,比单纯判断Connected属性更可靠。这个定时器像扫地机器人,定期清理失效连接。

把这些模块组装起来,你就得到了一个支持异步通信、自动重连、多客户端管理的聊天服务器。代码已通过VS2015编译测试,直接拉取代码后记得修改IP和端口参数。完整源码在Github的SocketChatRoom项目中,注释详细到每个方法都有使用示例,保证你半小时内就能魔改成自己的通信框架。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/4 12:49:53

AutoGLM-Phone日程管理应用:会议安排自动同步案例

AutoGLM-Phone日程管理应用&#xff1a;会议安排自动同步案例 1. Open-AutoGLM&#xff1a;手机端AI Agent的开源新范式 你有没有这样的经历&#xff1f;刚开完一场线上会议&#xff0c;正准备记录时间、添加日历提醒&#xff0c;结果电话又来了&#xff0c;手忙脚乱中漏掉了…

作者头像 李华
网站建设 2026/3/8 21:31:15

Sambert模型权重来源?IndexTeam协议合规说明

Sambert模型权重来源&#xff1f;IndexTeam协议合规说明 1. Sambert 多情感中文语音合成——开箱即用版 你是否在寻找一个真正“拿来就能用”的中文语音合成方案&#xff1f;市面上不少TTS项目虽然开源&#xff0c;但一上手就遇到依赖缺失、接口报错、环境冲突等问题。今天介…

作者头像 李华
网站建设 2026/3/7 5:09:42

5分钟玩转SAM 3:零基础实现图像视频智能分割

5分钟玩转SAM 3&#xff1a;零基础实现图像视频智能分割 1. 快速上手&#xff0c;无需编程也能做智能分割 你有没有想过&#xff0c;只需要上传一张图或一段视频&#xff0c;输入一个物体名称&#xff0c;就能自动把目标从画面中精准“抠”出来&#xff1f;现在&#xff0c;这…

作者头像 李华
网站建设 2026/3/6 14:44:02

YOLO26企业应用实战:中小团队低成本部署完整手册

YOLO26企业应用实战&#xff1a;中小团队低成本部署完整手册 在视觉AI落地越来越普遍的今天&#xff0c;中小团队常面临一个现实困境&#xff1a;想用最新目标检测模型做业务&#xff0c;却卡在环境配置、依赖冲突、显存适配、训练调参这些“隐形门槛”上。YOLO26作为Ultralyt…

作者头像 李华
网站建设 2026/3/5 6:20:27

如何定制VAD模型?基于FSMN的微调迁移学习指南

如何定制VAD模型&#xff1f;基于FSMN的微调迁移学习指南 1. FSMN 语音端点检测 (VAD) 离线控制台部署指南 你是否在处理长段录音时&#xff0c;为手动切分有效语音而头疼&#xff1f;是否希望有一个工具能自动帮你剔除静音、精准定位每一段说话内容&#xff1f;今天要介绍的…

作者头像 李华
网站建设 2026/3/4 1:48:58

性能翻倍!Qwen3-Reranker-4B与vLLM的优化配置技巧

性能翻倍&#xff01;Qwen3-Reranker-4B与vLLM的优化配置技巧 1. 引言&#xff1a;为什么重排序性能如此关键&#xff1f; 在现代搜索、推荐和信息检索系统中&#xff0c;候选结果动辄成百上千&#xff0c;如何从中精准筛选出最相关的结果&#xff0c;是决定用户体验的核心环…

作者头像 李华