简体   繁体   English

UDP 所有客户端的 ReceiveAsync 中断

[英]UDP ReceiveAsync breaks for all clients

I have created a simple C# UDP server/client model where multiple clients can connect to the same server.我创建了一个简单的 C# UDP 服务器/客户端 model,其中多个客户端可以连接到同一台服务器。 They all use the same EndPoint to connect to: IPEndPoint(IPAddress.Any, 0);它们都使用相同的 EndPoint 连接到: IPEndPoint(IPAddress.Any, 0); When this happens, I spawn a new task that listens for incoming messages on the given remoteEndPoint using发生这种情况时,我会生成一个新任务,该任务使用以下方法侦听给定 remoteEndPoint 上的传入消息

SocketReceiveFromResult dataReceived = await socket.ReceiveFromAsync(buffer, SocketFlags.None, endpoint).RemoteEndPoint;

This works great and new connections can connect and start sending messages to the server, which then relays those messages to the other clients.这很好用,新连接可以连接并开始向服务器发送消息,然后服务器将这些消息转发给其他客户端。 When I then close one of the client connections, I Close() the socket from that client but I then get a SocketException in the ReceiveLoop Task that says "An existing connection was forcibly closed by the remote host."然后,当我关闭其中一个客户端连接时,我关闭了该客户端的套接字,但随后在 ReceiveLoop 任务中收到了一个 SocketException,提示“现有连接已被远程主机强行关闭”。 This wouldn't be a problem at all, but it happens for all the connections, even the initial port that listens for incoming requests.这根本不是问题,但它发生在所有连接上,甚至是侦听传入请求的初始端口。

 try
 {
     if (isConnected)
     {
         UdpProtocol.RequestFromData requestFromData = await socket.ReceiveFromAsync(buffer, SocketFlags.None, endpoint);
         onMessageReceived?.Invoke(requestFromData.JsonObject);
      }
 }
 catch (SocketException exception)
 {
     onConnectionClosed?.Invoke();
 }

How do I terminate the connection properly without causing all other client connections to also terminate?如何正确终止连接而不导致所有其他客户端连接也终止?

After searching for a long time, I came upon this thread: C# UDP An existing connection was forcibly closed by the remote host经过很长时间的搜索,我发现了这个线程: C# UDP 一个现有的连接被远程主机强行关闭

apparently, UDP sockets listen to "ICMP messages and throwing exceptions when they are received. If the port is no longer listening (after the hard crash), the ICMP message causes the 'forcibly closed' exception."显然,UDP sockets 收听“收到 ICMP 消息并抛出异常。如果端口不再监听(在硬崩溃后),ICMP 消息会导致‘强制关闭’异常。”

This code works to create a socket that doesn't listen for such events.此代码用于创建不侦听此类事件的套接字。

        socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        const int SIO_UDP_CONNRESET = -1744830452;
        socket.IOControl((IOControlCode)SIO_UDP_CONNRESET, new byte[] { 0, 0, 0, 0 }, null);
        socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.PacketInformation, true);
        IPEndPoint server = new IPEndPoint(IPAddress.Any, 30000);
        socket.Bind(server);

putting it here solely for future references.放在这里仅供将来参考。

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

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