首页/新闻资讯/正文详情

C# UDP通信实战包:解决Send无响应、Receive卡死、Wireshark抓不到包

发布时间:2026/9/28 1:17:29 来源:云帆数科 栏目:资讯中心
C# UDP通信实战包:解决Send无响应、Receive卡死、Wireshark抓不到包
简介本资源是一份面向C#初学者与网络编程实践者的UDP通信入门示例工程聚焦局域网环境下的轻量级网口通讯开发。它通过完整可运行的客户端/服务器双项目结构系统演示UdpClient类在数据发送、接收、端点绑定及异常处理等核心环节的典型用法适用于物联网设备调试、工业现场测控通信、实时音视频前传等对时延敏感但容错性要求可控的场景。压缩包共63个文件含18个C#源码文件.cs、2个解决方案.sln与2个项目文件.csproj辅以配置文件.config、资源文件.resources及调试符号.pdb整体仅117KB结构精简、开箱即用。目前已有316人学习下载读者可直接编译运行双端程序结合Wireshark抓包验证通信流程并参考代码中清晰的注释与端点配置逻辑快速掌握UDP无连接通信的实现要点与常见避坑指南。1. C# UDP通信实战包一个能直接跑通的网口通讯测起点专治“Send没反应、Receive卡死、Wireshark抓不到包”三连翻车你是不是也遇到过刚写完C# UDP客户端Send()调用成功但对方死活收不到Receive()一执行就卡住不动调试器里线程全挂起Wireshark打开一看——本该飞出去的UDP包压根没出现在网卡上别急这不是你代码写错了而是缺了一套经过真实局域网设备联调验证、带完整Client/Server双工程、含端口绑定逻辑和异常兜底的最小可运行骨架。这个C#UDP.zip就是这么个东西它不是教学PPT里的伪代码也不是博客里截一半的片段而是一份开箱即用的网口通讯测基线——两个VS解决方案C_UDP_Client.sln和C_UDP_Server.sln各自带.v12.suo用户配置说明它真被某位工程师在VS2012环境里反复编译调试过。它解决的不是“UDP是什么”而是“为什么我的C# UDP程序在工控现场连不上PLC、扫不到传感器、发不出心跳帧”。适合正在做上位机、设备对接、协议仿真或被甲方临时塞进“今晚必须让两台嵌入式盒子通上”的一线开发者。别再从零搭Socket了先拿这套跑通再往上叠重传、校验、分包逻辑。2. 从UdpClient到真实网口为什么这个包的结构比教科书更贴近产线需求2.1 Client/Server双工程分离不是Demo是部署逻辑的预演这个压缩包里明明白白放着C_UDP_Client和C_UDP_Server两个独立文件夹每个都包含完整的.sln和.csproj。这不是为了凑数——它强制你思考谁该监听、谁该主动发、端口如何错开。比如 Server 工程默认监听12345端口Program.cs里new UdpClient(12345)而 Client 发送目标固定为127.0.0.1:12345或你改写的192.168.1.100:12345。这种分离避免了新手常犯的“同一个进程既Bind又Connect到同一端口”的自锁陷阱。更关键的是Server 工程里UdpClient实例是全局静态持有的见ServerForm.cs的private static UdpClient _udpServer且StartListening()方法用Task.Run(() ListenLoop())启动后台接收循环——这模拟了真实服务端需长期驻留、不阻塞UI的场景而不是教科书里那个Receive()一调就卡死的控制台阻塞模型。// C_UDP_Server/ServerForm.cs 关键片段 private static UdpClient _udpServer; private static IPEndPoint _remoteEndPoint new IPEndPoint(IPAddress.Any, 0); public static void StartListening() { _udpServer new UdpClient(12345); // 绑定本地端口 Task.Run(() ListenLoop()); // 后台持续接收 } private static void ListenLoop() { while (true) { try { UdpReceiveResult result _udpServer.Receive(ref _remoteEndPoint); string msg Encoding.UTF8.GetString(result.Buffer); // 日志输出、UI更新、协议解析... } catch (ObjectDisposedException) { break; } // Close时退出 catch (SocketException ex) when (ex.ErrorCode 10004) { /* 被中断忽略 */ } catch (Exception ex) { /* 记录错误但不停止循环 */ } } }提示这段代码里UdpReceiveResult替代了老旧的Receive(byte[], ref IPEndPoint)是 .NET Framework 4.5 推荐用法自动处理缓冲区管理和端点提取避免手动new byte[1024]的越界风险。2.2 网口通讯测的核心绑定IP与广播地址的显式控制很多初学者以为UdpClient(12345)就万事大吉结果在多网卡机器如笔记本有WiFi有线上死活不通。这个包的 Client 工程里SendToServer()方法明确构造了IPEndPoint// C_UDP_Client/ClientForm.cs private void SendToServer(string message) { try { // 关键显式指定发送网卡避免系统选错接口 IPAddress localIP GetLocalIPv4(); // 自定义方法见下文 IPEndPoint serverEP new IPEndPoint(IPAddress.Parse(192.168.1.100), 12345); using (UdpClient client new UdpClient()) { // 强制绑定到特定网卡可选但调试时极有用 client.Client.Bind(new IPEndPoint(localIP, 0)); byte[] data Encoding.UTF8.GetBytes(message); client.Send(data, data.Length, serverEP); } } catch (Exception ex) { MessageBox.Show($发送失败: {ex.Message}); } } // 获取本机第一个可用IPv4地址跳过127.0.0.1 private IPAddress GetLocalIPv4() { foreach (var ip in Dns.GetHostAddresses(Dns.GetHostName())) if (ip.AddressFamily AddressFamily.InterNetwork !IPAddress.IsLoopback(ip)) return ip; throw new Exception(未找到有效IPv4地址); }这段代码的价值在于它把“网口通讯测”从抽象概念落地为可干预的物理层选择。当你用Wireshark抓包发现UDP包从192.168.1.101发出却收不到回应立刻就能想到——Client是否绑到了192.168.1.101Server监听的12345端口是否被防火墙拦截而不是在UdpClient文档里大海捞针。2.3 UDP分包与组包的预留接口为工业协议打基础虽然当前代码只发短文本但C_UDP_Server的ListenLoop()里result.Buffer是原始字节数组C_UDP_Client的SendToServer()也接受byte[]。这意味着它天然支持后续扩展比如你要对接Modbus UDP功能码寄存器地址数据、或自定义二进制协议前4字节长度头负载。包里没写具体协议解析但结构已预留——你只需在string msg Encoding.UTF8.GetString(result.Buffer);这行下面插入if (result.Buffer.Length 4) { int len BitConverter.ToInt32(result.Buffer, 0); ... }即可。这种设计比“全ASCII字符串通信”的Demo更接近真实产线西门子S7-1200的UDP组播、K210与STM32的指令帧、甚至某些国产PLC的私有协议都依赖这种裸字节操作。3. 网口通讯测四步法从编译到Wireshark验证的闭环流程3.1 编译与端口检查先让两个进程活下来解压后用 Visual Studio2012及以上分别打开C_UDP_Server.sln和C_UDP_Client.sln。不要直接F5——先检查项目属性右键Server项目 → “属性” → “应用程设置” → 确认目标框架为.NET Framework 4.5或更高因用了UdpReceiveResult。然后编译Server若报错CS0234: 命名空间“System.Net.Sockets”中不存在类型或命名空间名“UdpClient”说明目标框架太低需升级。编译成功后打开命令行执行netstat -ano | findstr :12345若看到TCP 0.0.0.0:12345 0.0.0.0:0 LISTENING 12345PID为你Server进程ID说明端口已成功绑定。这是网口通讯测的第一道门槛——端口没被占用进程没崩溃。3.2 局域网IP配置让Client知道往哪发Server启动后记下其所在机器的IPv4地址如192.168.1.100。Client工程里ClientForm.cs的serverIPTextBox默认值就是192.168.1.100你只需确认Client机器和Server机器在同一子网如Client是192.168.1.101且双方防火墙允许UDP 12345端口入站/出站。Windows防火墙设置路径控制面板 → Windows Defender 防火墙 → 高级设置 → 入站规则 → 新建规则 → 端口 → UDP → 特定本地端口12345→ 允许连接 → 域/专用/公用全勾选。3.3 Wireshark抓包验证眼见为实的通信证据启动Wireshark选择Client机器的物理网卡非Loopback过滤条件输入udp.port 12345。点击Client的“发送”按钮立即观察抓包窗口应看到一条UDP协议行Source IP为Client地址Destination IP为Server地址Info列显示UDP 12345 → 12345。若无此包问题必在Client侧代码未执行Send、网卡选错、防火墙拦截若有发送包但无Server回包问题在Server侧未监听、进程崩溃、防火墙拦截入站。这是网口通讯测最硬核的证据链——不靠Console.WriteLine靠网络层原始数据说话。3.4 消息内容与编码UTF8还是ASCII别让乱码毁掉调试Client发送框输入中文“测试”Server日志显示“娴嬭瘯”这是典型的编码不一致。包里默认用Encoding.UTF8但某些旧设备如部分PLC、传感器只认Encoding.ASCII。此时需同步修改Client和Server两端// 两端同时改为 byte[] data Encoding.ASCII.GetBytes(message); // 发送端 string msg Encoding.ASCII.GetString(result.Buffer); // 接收端注意Encoding.Default系统ANSI绝对禁用它在不同电脑上结果不同是产线部署的定时炸弹。4. 避坑指南那些让C# UDP网口通讯测失败的血泪经验4.1 现象ClientSend()返回成功但ServerReceive()永远不触发原因Server的UdpClient实例被GC回收或Receive()调用后未重置IPEndPoint。常见于把UdpClient声明为局部变量、或在Receive()后未用ref传递端点。解决Server必须用静态字段持有UdpClient如private static UdpClient _server且Receive()必须传入ref IPEndPoint如client.Receive(ref remoteEP)否则下次接收时端点为空系统无法路由响应包。4.2 现象Wireshark能看到发送包但Server收不到或Server能收Client收不到回包原因多网卡环境下UdpClient默认绑定0.0.0.0但操作系统可能将响应包路由到错误网卡。尤其当Client和Server在同一台机器用127.0.0.1测试时UdpClient可能绑定到127.0.0.1而非0.0.0.0导致跨网卡通信失败。解决Client发送前显式client.Client.Bind(new IPEndPoint(localIP, 0))Server监听时用new UdpClient(new IPEndPoint(IPAddress.Any, 12345))明确绑定0.0.0.0而非仅端口号。4.3 现象Server连续接收多条消息但UdpReceiveResult.Buffer长度忽大忽小甚至出现乱码原因UDP无边界Receive()每次返回一个完整UDP数据报但应用层协议若未定义帧头如长度字段则无法区分多个短消息是否被合并或拆分。例如Client连续发两次“ABC”、“DEF”Server可能一次收到“ABCDEF”或分两次。解决在发送前添加帧头。Client端byte[] payload Encoding.UTF8.GetBytes(ABC); byte[] frame new byte[4 payload.Length]; BitConverter.GetBytes(payload.Length).CopyTo(frame, 0); // 前4字节存长度 payload.CopyTo(frame, 4); client.Send(frame, frame.Length, serverEP);Server端接收后先读前4字节得长度len再取frame.Skip(4).Take(len)解析。4.4 现象程序运行几小时后Receive()抛出SocketException错误码10054远程主机强迫关闭连接原因这不是TCP的“连接关闭”而是UDP的“端口不可达”ICMP错误。当Server进程崩溃、防火墙策略变更、或目标IP设备断电时Client继续发包路由器会返回ICMP Port Unreachable.NET将此转为SocketException。解决Receive()外层加try-catch捕获SocketException并检查ex.ErrorCode 10054此时应记录告警并尝试重连如重启UdpClient而非让整个线程退出。4.5 现象Client向广播地址255.255.255.255发包Server收不到原因现代Windows默认禁用受限广播Limited Broadcast且UdpClient对255.255.255.255的处理不如指定子网广播地址如192.168.1.255可靠。解决改用子网广播地址。先获取本机子网掩码var host Dns.GetHostEntry(Dns.GetHostName()); foreach (var addr in host.AddressList) if (addr.AddressFamily AddressFamily.InterNetwork) { var mask GetSubnetMask(addr); // 自定义方法查网卡配置 var broadcast GetBroadcastAddress(addr, mask); // 192.168.1.255 serverEP new IPEndPoint(broadcast, 12345); break; }5. 工业现场进阶技巧用这个包快速搭建PLC/传感器网口通讯测基线5.1 模拟西门子S7-1200 UDP组播三行代码切换模式S7-1200的UDP通信常使用组播地址224.0.0.100IANA注册的工业组播地址。要复用这个包只需改Server的绑定方式// C_UDP_Server/ServerForm.cs 修改 ListenLoop() 前的初始化 IPAddress multicastAddr IPAddress.Parse(224.0.0.100); IPEndPoint groupEP new IPEndPoint(multicastAddr, 12345); _udpServer new UdpClient(); _udpServer.JoinMulticastGroup(multicastAddr); // 关键加入组播组 _udpServer.Client.Bind(groupEP); // 绑定到组播地址端口Client发送时目标IPEndPoint改为new IPEndPoint(IPAddress.Parse(224.0.0.100), 12345)。这样一台Server可被多台Client同时监听完美模拟PLC向多个HMI广播状态的场景。5.2 对接RS485转UDP网关协议转换层的轻量实现很多现场用“RS485转UDP网关”如MOXA EDS-205A将串口设备接入以太网。这类网关通常将串口数据原样封装为UDP包目标端口即网关的UDP监听端口。此时你的C_UDP_Server就是网关的“上位机”——只需在ListenLoop()中解析收到的字节流// 假设网关转发Modbus RTU帧格式[SlaveID][Function][Data...][CRC] if (result.Buffer.Length 6) // 最小Modbus帧长 { byte slaveID result.Buffer[0]; byte function result.Buffer[1]; if (function 0x03) // 读保持寄存器 { ushort startReg BitConverter.ToUInt16(result.Buffer, 2); ushort regCount BitConverter.ToUInt16(result.Buffer, 4); // 构造响应帧并Send回网关... } }这个包的价值就在于它提供了干净的UDP收发通道让你专注协议逻辑而非Socket底层。5.3 网口通讯测自动化用PowerShell批量验证端口连通性产线部署前常需验证数十台设备的UDP端口是否可达。基于此包可写一个PS脚本调用Client.exe传参发送测试帧# Test-UDPPort.ps1 param($TargetIP, $Port 12345, $TimeoutMS 2000) $testMsg PING_ (Get-Date -Format yyyyMMddHHmmss) # 调用编译好的Client.exe传入IP和消息 .\C_UDP_Client\bin\Debug\Client.exe $TargetIP $testMsg | Out-Null # 等待2秒检查Server日志文件是否有该消息 Start-Sleep -Milliseconds $TimeoutMS $logPath .\C_UDP_Server\log.txt if (Select-String -Path $logPath -Pattern $testMsg -Quiet) { Write-Host $TargetIP:$Port ✅ -ForegroundColor Green } else { Write-Host $TargetIP:$Port ❌ -ForegroundColor Red }将此脚本与设备IP列表结合即可一键生成通讯测报告替代人工点按。从那以后我每次做网口通讯测都强制走一遍“编译→netstat查端口→Wireshark抓包→日志查编码”四步闭环哪怕只是改一行Encoding。因为UDP的不可靠性不是缺陷而是它的契约——它把可靠性交还给应用层而这份C#UDP.zip就是帮你把契约写清楚的第一张纸。希望帮到你。本文还有配套的精品资源点击获取

相关推荐

显示驱动板卡低功耗设计:从电源树到背光调度的系统方法
显示驱动板卡低功耗设计:从电源树到背光调度的系统方法

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/28 1:17:29

HFish跨平台蜜罐平台v2.2.0部署与实战:从节点配置到攻击告警
HFish跨平台蜜罐平台v2.2.0部署与实战:从节点配置到攻击告警

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/28 1:17:29

FPGA XADC DRP接口读取温度电压完整教程:从IP配置到时序实现
FPGA XADC DRP接口读取温度电压完整教程:从IP配置到时序实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/28 1:17:23

嵌入式Linux驱动开发全流程:设备树、VID/PID匹配与调试实战
嵌入式Linux驱动开发全流程:设备树、VID/PID匹配与调试实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/28 1:55:30

DSA91304A高速示波器实战:带宽、探头与眼图测量要点
DSA91304A高速示波器实战:带宽、探头与眼图测量要点

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/28 1:55:30

CANoe LIN网络搭建实战:LDF导入、调度表配置与避坑指南
CANoe LIN网络搭建实战:LDF导入、调度表配置与避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/28 1:55:30

用Python打造硬件自动化测试:PyCircuit 6实现电路仿真与批量验证
用Python打造硬件自动化测试:PyCircuit 6实现电路仿真与批量验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/28 1:55:29

Verdi信号追踪实战:从波形异常到根因定位的完整调试方法
Verdi信号追踪实战:从波形异常到根因定位的完整调试方法

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/28 1:55:29

Jetson Orin NX无头远程桌面实战:HDMI欺骗器与RealVNC配置指南
Jetson Orin NX无头远程桌面实战:HDMI欺骗器与RealVNC配置指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/28 1:55:23

MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现

简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01

汕头网站建设制作厂家避坑指南:5大注意事项救急
汕头网站建设制作厂家避坑指南:5大注意事项救急

汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01

多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习

简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01

制作网页比较方便的软件怎么选?一文搞懂避坑指南
制作网页比较方便的软件怎么选?一文搞懂避坑指南

制作网页比较方便的软件怎么选?一文搞懂避坑指南 很多老板一上来就问:做个网站多少钱?但我反问他:你的域名买了吗?服务器租了吗?他一脸懵。这就是典型的“域名服务器搞不懂”。别急,今天咱们不聊虚的,直接 一文搞懂 那些让你头秃的技术名词。… · 2026/9/28 0:00:06

婚恋网站实战案例:避开3个高价坑,省钱50%还能跑赢流量
婚恋网站实战案例:避开3个高价坑,省钱50%还能跑赢流量

婚恋网站实战案例:避开3个高价坑,省钱50%还能跑赢流量 找婚恋网站建站公司,最怕的就是被坑高价。很多同行跟我吐槽,报价单上写得模棱两可,功能栏里全是“高级定制”、“专属UI”,结果落地全是套壳。今天不聊虚的,直接甩几个我经手的 实战案例… · 2026/9/28 0:00:19

济南做网站多少钱:3个案例拆解,防黑源码下载全攻略
济南做网站多少钱:3个案例拆解,防黑源码下载全攻略

济南做网站多少钱:3个案例拆解,防黑源码下载全攻略 上周济南一个做建材的老板找我,脸都绿了。他的官网首页弹出了赌博广告,后台被植入了挖矿脚本。他慌得问我:“网站被黑挂马不知道怎么办?能不能直接找之前的外包公司要源码下载,看看哪里被动了手脚?… · 2026/9/28 0:00:25

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码