C#UDP远程主机强制关闭现有连接

Rhe*_*zon 5 c# udp network-programming

我正在为UDP使用异步方法处理多个客户端的游戏创建一个服务器,并且我专门研究干净的断开逻辑.当客户端硬崩溃(他们的程序在没有正确的断开逻辑的情况下关闭)readCallback时,服务器上会抛出SocketException

远程主机强制关闭现有连接

这是有道理的,但是当读被触发循环的下一次read崩溃,尽管异常回调被处理.

    private void connectedState()
    {
        while (connected)
        {
            //reset the trigger to non-signaled
            readDone.Reset();

            read(socket);

            //block on reading data
            readDone.WaitOne();
        }
    }


    private void read(Socket sock)
    {
        // Creates an IpEndPoint to capture the identity of the sending host.
        IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
        EndPoint senderRemote = sender;

        // Create the state object.
        StateObject state = new StateObject();
        state.workSocket = sock;

        //crashes after an exception is caught within the callback
        sock.BeginReceiveFrom(state.buffer, 0, StateObject.MESSAGE_SIZE, SocketFlags.None, ref senderRemote, new AsyncCallback(readCallback), state);
    }


    private void readCallback(IAsyncResult ar)
    {
        StateObject state = (StateObject)ar.AsyncState;
        Socket sock = state.workSocket;

        EndPoint senderRemote = new IPEndPoint(IPAddress.Any, 0);

        try
        {
            // Read data from the client socket. 
            int bytesRead = sock.EndReceiveFrom(ar, ref senderRemote);

            if (bytesRead <= 0)
            {
                //handle disconnect logic
            }
            else
            {
                //handle the message received
            }
        }
        catch (SocketException se)
        {
            Console.WriteLine(se.ToString());
        }

        // Signal the read thread to continue
        readDone.Set();
    }
Run Code Online (Sandbox Code Playgroud)

抛出两个异常,其中一个我相信被抓住了:


抛出异常:"System.Net.Sockets.SocketException"在System.dll中System.Net.Sockets.SocketException(0X80004005):一个现有的连接被强制通过在System.Net.Sockets.Socket.EndReceiveFrom远程主机(IAsyncResult的asyncResult关闭中,端点和端点)在CardCatacombs.Utilities.Networking.UDPNetworkConnection.readCallback(IAsyncResult的AR)在C:\用户\ kayas \桌面\实习\源\ CardCatacombs\CardCatacombs \公用事业\网络\ UDPNetworkConnection.cs:线424

抛出异常:"System.Net.Sockets.SocketException"在System.dll中System.Net.Sockets.SocketException(0X80004005):一个现有的连接被强制由远程主机在System.Net.Sockets.Socket.DoBeginReceiveFrom(字节[关闭]缓冲区,Int32偏移量,Int32大小,SocketFlags socketFlags,EndPoint endPointSnapshot,SocketAddress socketAddress,OverlappedAsyncResult asyncResult)


我希望能够干净地处理客户端崩溃并继续运行,因为有其他客户端连接到服务器.

jam*_*811 11

这个论坛帖子中,似乎UDP套接字也在接收ICMP消息并抛出异常时收到它们.如果端口不再侦听(在硬崩溃之后),ICMP消息将导致"强制关闭"异常.

如果不需要,可以在创建UdpClient时使用以下代码禁用此异常,如上文所述:

public const int SIO_UDP_CONNRESET = -1744830452;
var client = new UdpClient(endpoint);
client.Client.IOControl(
    (IOControlCode)SIO_UDP_CONNRESET, 
    new byte[] { 0, 0, 0, 0 }, 
    null
);
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,太奇怪了,无连接协议可以“重置”。 (4认同)