C#UDP远程主机

时间:2016-07-04 20:41:28

标签: c# network-programming udp

我正在使用异步方法为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();
    }

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

抛出异常:&#39; System.Net.Sockets.SocketException&#39;在System.dll中 System.Net.Sockets.SocketException(0x80004005):远程主机强制关闭现有连接    在System.Net.Sockets.Socket.EndReceiveFrom(IAsyncResult asyncResult,EndPoint&amp; endPoint)    在CardCatacombs.Utilities.Networking.UDPNetworkConnection.readCallback(IAsyncResult ar)中的C:\ Users \ kayas \ Desktop \ Practicum \ Source \ CardCatacombs \ CardCatacombs \ Utilities \ Networking \ UDPNetworkConnection.cs:line 424

抛出异常:&#39; System.Net.Sockets.SocketException&#39;在System.dll中 System.Net.Sockets.SocketException(0x80004005):远程主机强制关闭现有连接    at System.Net.Sockets.Socket.DoBeginReceiveFrom(Byte [] buffer,Int32 offset,Int32 size,SocketFlags socketFlags,EndPoint endPointSnapshot,SocketAddress socketAddress,OverlappedAsyncResult asyncResult)

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

1 个答案:

答案 0 :(得分:10)

this forum thread开始,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
);