Windows下UDP连接被重置错误10054

10 篇文章 0 订阅

转载地址:https://www.cnblogs.com/leading/archive/2012/06/24/udp-connection-reset-10054-under-windows.html

因为这个问题,我很想抽微软。网上其他人有类似的问题,我也碰到了,没有很好的解决方案。这个问题是Winsock所特有的(最起码所有的问题都是在Windows平台下)。一般在使用UDP Socket时,我们发出去数据,是不管它到不到达的,而且UDP并不是面向连接的,所以在收到这个错误时,会感觉很奇怪:“连接被重置10054”。

这个错误一般是使用UDP Socket接受时收到(这里我不讲具体的语言了,不管你用C#、Python还是C,在Windows下都会有类似的问题,只要你调用类似ReceiveFrom函数)。这是上一次Send操作向一个地址发送,但是那个地址没有Socket监听(例如对等体崩溃),那么ICMP控制协议会向我们发送一个Port Unreachable错误,当然这个错误应该包含对方的详细地址等信息,但是Winsock把这个错误转化为Connection Reset,在你下一次调用读操作的时候,引发异常,却没把详细信息给你——例如用C#接受到的对方地址是0.0.0.0。

而这个问题最要命的是,如果你不采取措施,每次调用读操作都会引发该异常!唯一恢复正常的办法就是把Socket关掉,重开。这就非常要命:你要实现一个UDP服务器,把收到的音频发给所有的客户,如果某个客户崩溃了或者网络不好,你的Send不会出问题,但是你Receive的时候却出了问题!好吧,你捕获了异常,重新Receive,还是异常!好吧,你关掉Socket重新建立,但是因为不知道是哪个客户出了问题,所以不能及时把他的地址从发送列表里去除(即使使用心跳检测也要等几秒种),下次Send还是这样,你就不停地关闭创建Socket,谁受的了?

网络上的讨论,最后要么说这是一个bug,要么使用如下代码(以C#为例)

const int SIP_UDP_CONNRESET=-1744830452;
socket.IOControl(SIP_UDP_CONNRESET, new byte[] {0, 0, 0, 0}, null);

设置这个选项忽略那个Reset错误,这样不用重建Socket,只不过每次Socket都会向一些已经关闭的客户发包,浪费了服务器资源;只能通过其他机制确定客户端已经断开,延迟一段时间后才能确定哪个客户端出问题。

我想跟微软说的是,你丫要不就在出问题的地方抛出异常,不然的话把详细错误给了也行,再不行不要强制出一个错误整个Socket就毁了,结果一个都没做到,默认的行为不是正常的UDP行为,还改错误类型,真是欠抽!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Windows 操作系统中,UDP 组播是一种同时向多个接收方传递数据包的通信方式。使用 UDP 协议进行组播通信可以减少网络流量,提高通信效率和可靠性。 在 C 语言中实现 UDP 组播,需要使用 Winsock API 进行网络编程。通过调用相关的库函数,实现 UDP 的创建、绑定、发送和接收等操作。 创建 UDP Socket:使用 socket() 函数创建 UDP Socket,确定 IP 地址族(IPv4/IPv6)、协议类型(UDP)和 Socket 类型(组播 Socket)。 绑定 Socket:使用 bind() 函数将 Socket 与指定的 IP 地址和端口号绑定。 发送数据包:使用 sendto() 函数向指定的组播地址和端口号发送数据包。 接收数据包:使用 recvfrom() 函数从组播组中接收数据包,并处理接收到的数据。 在使用 UDP 组播时,需要注意以下几点: 1. 组播地址需要在特定的范围内,一般为224.0.0.0至239.255.255.255的范围内,防止与其他网络通信冲突。 2. 不同的操作系统和网络环境下,组播协议的实现可能会有差异,需要根据具体情况进行调试和优化。 3. 组播通信有时会出现丢包或者乱序的情况,需要通过网络协议栈的相关机制进行处理,提高通信可靠性。 总之,UDP 组播是一种高效、可靠、灵活的网络通信方式,适用于多种应用场景,如视频直播、数据传输、分布式计算等。在 C 语言中实现 UDP 组播,需要掌握网络编程基础知识和相关的库函数,结合实际应用需求进行调试和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值