C# WinForms TCP Socket 服务端
一、Socket 基础概念1. 什么是 Socket套接字Socket 是网络通信的通信端点可以理解为程序进行网络数据收发的 “接口 / 电话机”。 两台程序想要通过网络通信两端都必须创建 Socket。IP 地址定位网络中的电脑住址端口号定位电脑上运行的具体程序房间号Socket程序收发网络数据的载体2. TCP Socket 创建参数解析new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)AddressFamily.InterNetwork使用 IPv4 地址协议SocketType.Stream数据流模式面向连接对应 TCPProtocolType.Tcp指定通信协议为 TCPTCP 特点先建立连接、可靠传输、不会丢包、有序适合设备通信、上位机、聊天程序。3. TCP 通信角色区分服务端 Socket (server)固定 IP 端口被动等待客户端连接客户端 Socket (client)主动发起连接连接服务端 IP 端口重点server 套接字只负责接收连接每接入一个客户端会生成独立 client 套接字单独通信。二、TCP 服务端标准开发五大步骤代码主线实例化 Socket 对象new Socket()绑定 Bind将 Socket 绑定本机 IP 端口IPEndPoint开启监听 Listen开始等待客户端发起连接接受连接 Accept ()阻塞等待客户端接入生成客户端 Socket循环接收数据 Receive ()持续读取客户端发送的字节数据三、核心类详解Dns域名解析类用来获取本机主机名、解析 IP 地址IPHostEntry主机信息实体包含本机所有 IP 地址列表IPAddress封装单个 IP 地址IPEndPoint IPAddress 端口号代表一个完整网络终端CancellationTokenSource线程令牌安全控制循环线程停止Encoding.UTF8字节数组与字符串互相转换网络传输只有 byte []四、本机 IPv4 自动获取逻辑解析IPHostEntry iPHost Dns.GetHostEntry(Dns.GetHostName()); foreach (IPAddress item in iPHost.AddressList) { if (item.AddressFamily AddressFamily.InterNetwork) { ipStr item.ToString(); } }逻辑说明Dns.GetHostName()获取电脑本机名称Dns.GetHostEntry()根据主机名拿到本机所有 IP遍历地址列表筛选InterNetwork类型只保留 IPv4 地址作用自动适配电脑 IP不用手动硬编码 IP 地址。五、端口说明int port 63323;端口范围0 ~ 655350~1023系统保留端口尽量不要使用推荐使用1024 ~ 65535 之间端口绑定代码IPAddress address IPAddress.Parse(ipStr); IPEndPoint endPoint new IPEndPoint(address, port); server.Bind(endPoint);监听开启server.Listen(100);Listen 参数最大等待连接队列长度。六、两种服务端模式对比模式 1AcceptDataSigle () 单客户端版本功能仅支持同时连接一个客户端运行逻辑开启 Task 异步线程执行server.Accept()阻塞等待客户端连接成功接入客户端 Socket 后进入 while 循环持续调用 Receive 读取数据重大缺陷新客户端发起连接时无法同时接入只能服务一个客户端工业通信、上位机项目不适用。模式 2AcceptDataMul () 多客户端版本【课程推荐方案】采用双层嵌套线程模型支持多个客户端同时连接外层线程while 循环不断执行server.Accept()持续监听、接收新客户端连接每成功连接一个客户端立刻创建独立线程处理收发。内层线程每个客户端独立线程为每一个客户端 Socket 单独开启任务循环接收该客户端下发的数据。核心思想一个客户端一条接收线程客户端之间互不干扰。七、数据接收相关知识点1. Receive () 接收数据byte[] buffer new byte[client.Available]; int length client.Receive(buffer);client.Available当前接收缓冲区中已经到达的字节数量Receive(buffer)将网络数据读取到字节数组 buffer返回实际收到字节长度⚠️ 网络传输底层只有字节数组字符串必须转 byte [] 发送收到 byte [] 再转回字符串展示。Encoding.UTF8.GetString(buffer); //字节数组 → 字符串2. WinForms 跨线程 UI 操作重中之重规则子线程不能直接操作窗体控件richTextBox、TextBox 等直接调用会报错跨线程操作无效。 解决方案使用Invoke()切换至 UI 主线程更新控件Invoke(new Action(() { richTextBox1.AppendText(Encoding.UTF8.GetString(buffer)); }));八、线程控制CancellationTokenSource创建令牌对象CancellationTokenSource cts new CancellationTokenSource();cts.Token传入 Task用于线程内部判断退出条件!cts.IsCancellationRequested循环条件判断是否请求终止线程调用cts.Cancel()即可触发信号结束 while 循环 作用优雅关闭线程避免暴力终止造成资源异常。代码结构外层监听线程使用 cts每个独立客户端接收线程单独创建 cts2。九、当前代码存在的缺陷与隐患考点重点记录buffer 数组分配方式错误new byte[client.Available]存在分包风险。TCP 是流式传输数据可能分多次到达Available 只代表当下缓冲区数据容易出现接收不全、丢数据。server.Accept()阻塞无法被令牌取消 Accept () 属于阻塞方法在等待客户端连接时就算触发 CancellationToken线程也不会立刻退出。没有处理客户端断开连接 客户端正常下线时Receive () 返回 0代码未判断 length0不会主动释放 Socket会持续进入异常循环。缺少 Socket 资源释放 客户端断开后没有执行client.Close()、client.Dispose()长期运行会内存泄漏、端口占用。异常处理简单粗暴 catch 只执行 break没有区分异常类型网络断开、程序报错、强制关闭等不方便调试排查。多客户端令牌对象未统一管理 每个客户端新建 cts2客户端大量接入时会创建大量令牌对象缺少统一回收机制。十、核心方法汇总表表格方法功能说明Socket.Bind(IPEndPoint)将套接字绑定本机 IP 与端口Socket.Listen(int)开启监听准备接收客户端连接Socket.Accept()阻塞等待客户端连接返回客户端 SocketSocket.Receive(byte[])接收客户端发送的字节数据Control.Invoke(Action)子线程安全更新窗体控件Dns.GetHostName()获取本机计算机名称Dns.GetHostEntry(hostName)通过主机名获取本机 IP 信息十一、完整程序运行流程窗体加载事件 Form1_Load 启动创建服务端 Socket自动获取本机 IPv4 地址组装 IPEndPointBind 绑定 IP 端口Listen 开启监听调用 AcceptDataMul () 启动多客户端监听线程线程阻塞等待客户端连接客户端连接成功 → 分配独立接收线程线程循环调用 Receive 接收字节数据通过 Invoke 切换 UI 线程将字节转为字符串显示到富文本框出现网络异常时跳出循环终止当前客户端接收任务十二、拓展补充Socket 分类TCPStream 流式套接字本次代码 UDPDatagram 数据报套接字无连接、不需要 Accept、速度快可能丢包。WebSocket 和 Socket 区别Socket 是底层网络通信接口WebSocket 是浏览器专用、基于 HTTP 升级后的长连接本质依旧依托 Socket 实现。上位机通信常用场景 Modbus TCP、传感器数据采集、PLC 通信、设备监控底层全部使用 TCP Socket 开发。namespace _1.服务端 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } Socket server null; private void Form1_Load(object sender, EventArgs e) { //1.实例化服务器对象 //参数1 地址类型 InterNetwork属于ipv4类型 InterNetworkV6属于ipv6类型 //参数2 SocketType.Stream 指定数据传输的时候使用数据流的方式进行传输 //参数3 指定通信协议 ProtocolType.Tcp 采用的tcp通信 server new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); //把服务器对象绑定给一个ip和端口号 //ip地址字符串 string ipStr ; //端口号 建议不要写太小 范围0-65535 int port 63323; //获取当前电脑的ip信息 //Dns.GetHostName()获取计算主机名称 //Dns.GetHostEntry() 通过主机名解析成对应的ip IPHostEntry iPHost Dns.GetHostEntry(Dns.GetHostName()); //iPHost.AddressList地址列表 foreach (IPAddress item in iPHost.AddressList) { if (item.AddressFamily AddressFamily.InterNetwork)//查询判断是不是ipv4的地址 { ipStr item.ToString(); } } //地址类型 IPAddress address IPAddress.Parse(ipStr);//把字符串转成地址类型 //终端对象包含ip和端口 IPEndPoint endPoint new IPEndPoint(address, port); server.Bind(endPoint);//绑定终端 //3.开启服务器 server.Listen(100);//容纳客户端数量 //使用哪些技术 //服务器可以接收多个客户端使用线程 //客户端需要不停的发消息需要while(true) for 一直处于接收状态 //多个客户端需要使用线程每个客户端需要发消息又得使用线程需要两层嵌套 //4.接收客户端发来的请求 //AcceptDataSigle();//接收单个客户端的方法 AcceptDataMul();//接收多个客户端 } CancellationTokenSource cts; CancellationTokenSource cts2; public void AcceptDataMul() { //接收客户端需要写在线程 cts new CancellationTokenSource(); Task.Run(() { while (!cts.IsCancellationRequested) { //接收多个客户端 Socket client server.Accept();// if (client null) { Console.WriteLine(客户端未连接); break; } if (client.Connected) //保证客户端正常连接 { //读取数据 一直读取 需要一个线程 cts2 new CancellationTokenSource(); Task.Run(() { while (!cts2.IsCancellationRequested) { try { //读取数据 byte[] buffer new byte[client.Available]; int length client.Receive(buffer); Invoke(new Action(() { richTextBox1.AppendText(Encoding.UTF8.GetString(buffer)); })); } catch(Exception) { break; } } },cts2.Token); } } },cts.Token); } public void AcceptDataSigle() { cts new CancellationTokenSource(); Task.Run(() { //server 服务器 //client 客户端 Socket client server.Accept();//接收客户端 //处理客户端发来的数据 while (!cts.IsCancellationRequested) { //定义字节数组 数组长度为读取的可用数据的长度 byte[] buffer new byte[client.Available]; //Receive()接收客户端的数据 int length client.Receive(buffer); Invoke(new Action(() { richTextBox1.AppendText(Encoding.UTF8.GetString(buffer)); })); } },cts.Token); } //1.创建服务器对象 new socket() //2.服务器对象绑定终端 Bind(IPEndPoint) //3.服务器开启监听 .listen //4.接收客户端连接请求 .accept() //5.接受发来的数据 .receive() } }十三、OSI七层网络模型1. 应用层面向应用程序给软件提供网络服务 协议HTTP、HTTPS、FTP、DNS、SMTP 数据单元数据2. 表示层数据编码、加密解密、压缩解压 作用统一数据格式不同系统能看懂数据 例图片 jpg、文本编码、SSL 加密旧划分3. 会话层建立、维持、断开两台应用之间通信会话 负责会话同步、断点恢复小总结应用、表示、会话三层 → TCP/IP 统一合并为【应用层】4. 传输层重点TCP/UDP 在这里端到端通信两个程序之间传输数据 协议TCP可靠、面向连接、有握手、重传文件传输、网页UDP不可靠、无连接、速度快直播、语音、游戏 设备防火墙 数据单元段 (Segment)5. 网络层寻址、路由选择跨网段传输 协议IP、ICMP、ARP (有争议)设备路由器数据单元包 (Packet)6. 数据链路层同一局域网内传输MAC 地址寻址 协议以太网协议 设备交换机、网卡数据单元帧 (Frame)7. 物理层传输电信号 / 光信号、比特流 网线、光纤、集线器、电压电平 数据单元比特 (bit) 0 和 1

相关新闻

勒让德多项式:从物理方程到正交基的推导与应用

勒让德多项式:从物理方程到正交基的推导与应用

1. 项目概述:从物理问题到数学工具 勒让德多项式,这个名字听起来有点学术,但如果你处理过球坐标系下的拉普拉斯方程、搞过电磁学里的多极展开,或者计算过量子力学中的角动量,那你一定绕不开它。它不是什么遥不可及的纯…

2026/9/18 3:21:28 阅读更多 →
机器学习-决策树

机器学习-决策树

概念: 决策树通过对训练样本的学习,建立分类规则,然后依据分类规则对新样本数据进行分类预测,属于有监督学习。 核心: 所有数据从根节点逐步落到叶子节点。 决策树主要有三种算法:ID3 算法、C4.5 算法、…

2026/9/22 0:22:54 阅读更多 →
从零部署Web应用:粉丝空间站项目实战与通用技术验证框架

从零部署Web应用:粉丝空间站项目实战与通用技术验证框架

这次我们来看一个名为“粉丝空间站”的项目。从名称和有限的材料来看,这很可能是一个面向内容创作者或社群运营者的工具,旨在帮助管理粉丝、增强互动或提供专属内容空间。对于技术博主、UP主或社群管理者而言,一个能稳定运行、支持自定义、且…

2026/9/12 8:05:21 阅读更多 →

最新新闻

3个高频坑让你少走弯路:applicable属性新手避坑指南

3个高频坑让你少走弯路:applicable属性新手避坑指南

3个高频坑让你少走弯路:applicable属性新手避坑指南 官方文档那一长串 applicable 定义,看两遍就晕了?别急,这不是你的问题。 很多新手在写权限控制或状态标记时,被 applicable 这个单词卡住。它不像 valid…

2026/9/22 4:03:27 阅读更多 →
5道金采网官网高频面试题:搞定StackTrace报错

5道金采网官网高频面试题:搞定StackTrace报错

5道金采网官网高频面试题:搞定StackTrace报错 面试时最怕什么?不是算法,而是环境配置和报错。 看着满屏红色的 StackTrace,脑子瞬间空白。 这不仅是技术坑,更是金采网官网相关岗位的 高频面试题 核心。…

2026/9/22 4:02:27 阅读更多 →
地城之光源码图解原理:3个致命坑让API全变

地城之光源码图解原理:3个致命坑让API全变

地城之光源码图解原理:3个致命坑让API全变 刚接手《地城之光》旧项目,版本一升级,API 直接炸了。 我盯着满屏的 404 和 Type Error ,头都大了。 别再盲目改代码了,得先搞懂这背后的 图解原理 。…

2026/9/22 4:02:27 阅读更多 →
3个高频面试题拆解printscreen实战,别再只背语法了

3个高频面试题拆解printscreen实战,别再只背语法了

3个高频面试题拆解printscreen实战,别再只背语法了 是不是刚背完 print(screen) 或者 print(screen.buffer)…

2026/9/22 4:02:27 阅读更多 →
廖雪峰git教程避坑指南:从报错到性能优化实战

廖雪峰git教程避坑指南:从报错到性能优化实战

廖雪峰git教程避坑指南:从报错到性能优化实战 盯着屏幕上一长串红色的 Error Trace,是不是感觉大脑瞬间宕机?那些看似天书的英文报错,往往只因为一个拼写错误或者权限缺失。别慌,作为过来人,我深知这种在廖雪峰git教程里卡壳的绝望感…

2026/9/22 4:02:27 阅读更多 →
jinjia进阶用法

jinjia进阶用法

Jinja2与Mako模板引擎深度对比:3个完整示例解决版本升级API变更难题 刚把项目从 Jinja2 2.x 升级到 3.x,或者从 Mako 迁移过来,发现 {{ variable }} 里的过滤器写法变了, {% extends…

2026/9/22 4:01:26 阅读更多 →

日新闻

3台商务办公笔记本实测:手写实现环境配置,告别卡半天

3台商务办公笔记本实测:手写实现环境配置,告别卡半天

3台商务办公笔记本实测:手写实现环境配置,告别卡半天 配置环境就卡半天?别怪机器慢,多半是你没选对工具链。在Java、Go或Python的项目现场, 手写实现…

2026/9/22 0:00:41 阅读更多 →
剑帝加点速查手册:3分钟搞懂核心逻辑

剑帝加点速查手册:3分钟搞懂核心逻辑

剑帝加点速查手册:3分钟搞懂核心逻辑 面试被问原理答不上来,是不是常态?别慌。很多开发者对着 GitHub 开源仓库里的代码发呆,看似简单实则暗藏玄机。今天这份【剑帝加点】速查手册,直接带你拆解核心实现,把面试必考的原理讲透。…

2026/9/22 0:00:41 阅读更多 →
手写实现图片压缩网站核心:搞定WebP转换与质量调优

手写实现图片压缩网站核心:搞定WebP转换与质量调优

手写实现图片压缩网站核心:搞定WebP转换与质量调优 复制来的代码跑不通不知道怎么调?别慌,这种“复制粘贴地狱”在开发圈太常见了。尤其是做 图片压缩网站…

2026/9/22 0:00:41 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/21 3:13:20 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/21 2:19:36 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/21 4:51:05 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/21 15:36:51 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/21 15:36:51 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/22 2:43:42 阅读更多 →