简体   繁体   English

如何从C#udp套接字异常中优雅地恢复

[英]How to recover gracefully from a C# udp socket exception

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. 上下文:我正在将一个Linux perl应用程序移植到C#,服务器侦听一个udp端口,并通过一个udp套接字维护与远程客户端的多个并发对话框。 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. 在测试期间,我向udp服务器发送大量数据包,随机重启客户端以观察服务器注册新连接。 The problem is this: when I kill a udp client, there may still be data on the server destined for that client. 问题是这样的:当我杀死一个udp客户端时,服务器上可能仍然存在发往该客户端的数据。 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. 当服务器尝试发送此数据时,它会返回icmp“无服务可用”消息,因此套接字上发生异常。

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. 我无法重用此套接字,当我尝试将C#异步处理程序与套接字关联时,它会抱怨异常,因此我必须关闭并重新打开服务器端口上的udp套接字。 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? 这是解决这个问题的唯一方法吗?肯定有一些“修复”udp套接字的方法,从技术上讲,UDP套接字不应该知道远程套接字的状态?

Any help or pointers would be much appreciated. 任何帮助或指针将不胜感激。 Thanks. 谢谢。

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. 如果您将UDP数据包发送到可能打开或未打开的某个IP /端口,则无法知道服务器是否到达目的地。

The only way for the server to know is to have the client send an ACK back. 服务器知道的唯一方法是让客户端发回ACK。 (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) 很明显,你的代码中正在发生其他事情(或者使用.Net udp实现)

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. 事实上,在使用UDP时,.Net与“连接”或“无连接”有所区别。

If you use code like this: 如果你使用这样的代码:

UdpClient udpClient = new UdpClient(11000); //sourceport
try{
     udpClient.Connect("www.contoso.com", 11000); //'connect' to destmachine and port
     // Sends a message to the host to which you have connected.
     Byte[] sendBytes = Encoding.ASCII.GetBytes("Is anybody there?");
     udpClient.Send(sendBytes, sendBytes.Length);

then apparently you are 'connected' 然后显然你是'连接'

However if you use code like this: 但是,如果您使用这样的代码:

     UdpClient udpClientB = new UdpClient();
     udpClientB.Send(sendBytes, sendBytes.Length, "AlternateHostMachineName", 11000);

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' 我不确定你的代码是什么样的,但是检查你是否正在使用不假设“连接”的正确命令集可能是值得的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM