C# 调用EndAccept并访问RemoteEndPoint后发生套接字未连接异常
访问服务器上已接受套接字的RemoteEndPoint属性时,有时会抛出SocketException:“套接字未连接” 这种情况偶尔会发生(比如每100次连接尝试中就有一次),并且只有在网络上存在明显的延迟时才会发生(例如10ms+,wifi网络)。似乎是某种比赛状态,但我不确定能做些什么来防止这种情况 服务器代码:C# 调用EndAccept并访问RemoteEndPoint后发生套接字未连接异常,c#,sockets,C#,Sockets,访问服务器上已接受套接字的RemoteEndPoint属性时,有时会抛出SocketException:“套接字未连接” 这种情况偶尔会发生(比如每100次连接尝试中就有一次),并且只有在网络上存在明显的延迟时才会发生(例如10ms+,wifi网络)。似乎是某种比赛状态,但我不确定能做些什么来防止这种情况 服务器代码: this.Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
this.Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
this.Socket.Bind(new IPEndPoint(IPAddress.Parse("0.0.0.0"), port));
this.Socket.Listen(0);
this.Socket.BeginAccept(OnSocketAccepted, null);
private void OnSocketAccepted(IAsyncResult ar)
{
var socket = Socket.EndAccept(ar);
var endPoint = socket.RemoteEndPoint; // SocketException: The socket is not connected
}
客户端代码:
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Connect(ip, port);
// times out after a couple of seconds if the exception happened on the server
服务器运行在ARMv7 rev4 Raspberry Pi 3b上的Mono 6.4.0.198上+
客户端正在Windows 10.NET framework 4.6.1控制台应用程序上运行
我认为EndAccept基本上可以保证套接字处于连接状态,并且可以设置RemoteEndPoint。我已经浏览了整个msdn EndAccept和RemoteEndPoint文档,没有发现任何明显的错误或误解。在调用EndAccept()之后和查询RemoteEndPoint之前,套接字可以关闭。它也可以在回调调用EndAccept()之前关闭,这也会引发套接字异常 这里可能会发生很多比赛情况,特别是当你的系统速度慢的时候。您可以检查套接字。已连接,但即使这样也不能保证 正确的方法是Try/Catch,然后优雅地退出或抛出一个不可恢复的套接字 e、 g
catch (SocketException ex)
#region SocketException
{
/// Some SocketExceptions we manage quietly. Others we surface as critical errors.
if ((SocketError)ex.ErrorCode == SocketError.AddressAlreadyInUse)
{
Log.Error("Endpoint failed to start. IPEndPoint {ipEndPoint} already in use.", this.localIPEndPoint.ToString());
// Execution will continue after finally{}
}
else
{
Log.Error(ex, "Endpoint has ended with an unrecoverable socket error:", Name);
throw;
}
}