如何从 C# udp 套接字异常中正常恢复
上下文:我正在将 Linux Perl 应用程序移植到 C#,服务器侦听 udp 端口并通过单个 udp 套接字与远程客户端维护多个并发对话。在测试过程中,我向 udp 服务器发送大量数据包,随机重新启动客户端以观察服务器注册新连接。问题是这样的:当我杀死一个udp客户端时,服务器上可能仍然有发往该客户端的数据。当服务器尝试发送此数据时,它会收到返回的 icmp“无服务可用”消息,因此套接字上会发生异常。
我无法重用此套接字,当我尝试将 C# 异步处理程序与套接字关联时,它会抱怨异常,因此我必须关闭并重新打开服务器端口上的 udp 套接字。这是解决这个问题的唯一方法吗?肯定有某种方法可以“修复”udp套接字,因为从技术上讲,UDP套接字不应该知道远程套接字的状态?
任何帮助或指示将不胜感激。谢谢。
Context: I'm porting a linux perl app to C#, the server listens on a udp port and maintains multiple concurrent dialogs with remote clients via a single udp socket. During testing, I send out high volumes of packets to the udp server, randomly restarting the clients to observe the server registering the new connections. The problem is this: when I kill a udp client, there may still be data on the server destined for that client. When the server tries to send this data, it gets an icmp "no service available" message back and consequently an exception occurs on the socket.
I cannot reuse this socket, when I try to associate a C# async handler with the socket, it complains about the exception, so I have to close and reopen the udp socket on the server port. Is this the only way around this problem?, surely there's some way of "fixing" the udp socket, as technically, UDP sockets shouldn't be aware of the status of a remote socket?
Any help or pointers would be much appreciated. Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为你说得对:“服务器不应该知道”。如果您将 UDP 数据包发送到某个可能打开或未打开的 IP/端口,则服务器无法知道它是否到达了目的地。
服务器知道的唯一方法是让客户端发回 ACK。 (此外,客户端和服务器都必须具有重新发送机制,以防丢失包)。
很明显,您的代码(或 .Net udp 实现)中发生了其他事情
编辑:
在尼古拉的评论之后,我检查了文档。事实上,.Net 在使用 UDP 时存在“连接”或“无连接”的区别。
如果您使用这样的代码:
那么显然您已“连接”
但是如果您使用这样的代码:
那么您可以发送给您选择的任何人而无需“连接”。
我不确定您的代码是什么样的,但可能值得检查您是否使用了不假定“连接”的正确命令集
I think you are right in saying: 'the server should not be aware'. If you send an UDP packet to some IP/port which may or may not be open, there is no way of knowing for the server if it reached it's destination.
The only way for the server to know is to have the client send an ACK back. (Also both the client and server must have resend mechanisms in place in cases of lost packages).
So clearly something else is going on in your code (or with the .Net udp implementation)
EDIT:
After Nikolai's remark I checked the docs. And indeed there is a distinction in .Net to about being 'connected' or 'connectionless' when using UDP.
If you use code like this:
then apparently you are 'connected'
However if you use code like this:
then you can send to whomever you choose without 'connecting'.
I'm not sure what your code looks like, but it might be worthwhile to check if you are using the correct set of commands which doesn't assume a 'connection'