C#UDP远程主机强行关闭了现有连接 [英] C# UDP An existing connection was forcibly closed by the remote host

查看:127
本文介绍了C#UDP远程主机强行关闭了现有连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am creating a server for a game that handles multiple clients over UDP using the asynchronous methods, and am specifically working on clean disconnect logic. When a client hard crashes (their program is closed without proper disconnect logic) the readCallback on the server throws the SocketException

远程主机强行关闭了现有连接

An existing connection was forcibly closed by the remote host

这很有意义,但是,当下次在 read 中的循环上触发读取时,尽管在回调中处理了异常,它还是崩溃了.

which makes sense, however when the read is triggered the next time on the loop in read it crashes despite the exception being handled in the callback.

    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();
    }

引发了两个异常,我相信其中一个会被捕获:

Two exceptions are thrown, one of which I believe is being caught:

引发的异常:System.dll中的"System.Net.Sockets.SocketException"System.Net.Sockets.SocketException(0x80004005):现有连接被远程主机强行关闭在System.Net.Sockets.Socket.EndReceiveFrom(IAsyncResult asyncResult,EndPoint& EndPoint)在C:\ Users \ kayas \ Desktop \ Practicum \ Source \ CardCatacombs \ CardCatacombs \ Utilities \ Networking \ UDPNetworkConnection.cs:line 424

Exception thrown: 'System.Net.Sockets.SocketException' in System.dll System.Net.Sockets.SocketException (0x80004005): An existing connection was forcibly closed by the remote host at System.Net.Sockets.Socket.EndReceiveFrom(IAsyncResult asyncResult, EndPoint& endPoint) at CardCatacombs.Utilities.Networking.UDPNetworkConnection.readCallback(IAsyncResult ar) in C:\Users\kayas\Desktop\Practicum\Source\CardCatacombs\CardCatacombs\Utilities\Networking\UDPNetworkConnection.cs:line 424

引发的异常:System.dll中的"System.Net.Sockets.SocketException"System.Net.Sockets.SocketException(0x80004005):现有连接被远程主机强行关闭在System.Net.Sockets.Socket.DoBeginReceiveFrom(Byte [] buffer,Int32 offset,Int32 size,SocketFlags socketFlags,EndPoint endPointSnapshot,SocketAddress socketAddress,OverlappedAsyncResult asyncResult)

Exception thrown: 'System.Net.Sockets.SocketException' in System.dll System.Net.Sockets.SocketException (0x80004005): An existing connection was forcibly closed by the remote host at System.Net.Sockets.Socket.DoBeginReceiveFrom(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags, EndPoint endPointSnapshot, SocketAddress socketAddress, OverlappedAsyncResult asyncResult)

由于其他客户端已连接到服务器,我希望能够彻底处理客户端崩溃并继续运行.

I would like to be able to cleanly handle a client crash and continue running since there are other clients connected to the server.

推荐答案

来自

From this forum thread, it seems that the UDP socket is also receiving 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.

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

If not wanted, this exception can be disabled using the following code when creating the UdpClient, explained in the above post:

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
);

这篇关于C#UDP远程主机强行关闭了现有连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆