【发布时间】:2016-11-06 14:44:05
【问题描述】:
我正在为一个游戏创建一个服务器,该服务器使用异步方法通过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();
}
抛出了两个异常,我认为其中一个被捕获了:
抛出异常: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 中的 CardCatacombs.Utilities.Networking.UDPNetworkConnection.readCallback(IAsyncResult ar) 处
抛出异常: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)
我希望能够干净地处理客户端崩溃并继续运行,因为还有其他客户端连接到服务器。
【问题讨论】:
-
不清楚代码在哪里崩溃。请澄清并发布例外情况。 Socket IO 没有特殊的异常规则。异常总是以相同的方式工作并且会被捕获。
-
请注意,您使用异步 IO 没有任何意义。由于您正在阻止事件,因此您会遇到两全其美的情况:回调和有限的可扩展性。使用sync IO,不要盲目复制不好的示例代码。
-
查看您的编辑:您仍然需要提供异常,以明确它发生的确切位置。另外,你所说的“崩溃”是什么意思?我应该马上问的。
-
我更新了帖子以包含引发的异常,并澄清了我所说的崩溃的意思。希望这会有所帮助,尽管示例代码显然没有显示行号
-
我对 APM 模式不是很熟悉。也许您还需要尝试保护 Begin 调用。你正确地保护了 End 调用。当然“句柄断开逻辑”逻辑也必须出现在catch中。如果没有更完整的代码和对症状的更好描述,很难说发生了什么。崩溃是否意味着控制台应用程序在没有警告的情况下退出?
标签: c# network-programming udp