C#UDP远程主机强行关闭了现有连接 [英] C# UDP An existing connection was forcibly closed by the remote host
问题描述
我正在为一个游戏创建服务器,该服务器使用异步方法通过 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屋!