我无法在这个主题上找到太多内容,但最近我一直在使用SocketAsyncEventArgs对象实现套接字服务器。我按照以下示例进行了操作:Code Project Example
我修改了数据处理类以满足我的需要,并且如果任何套接字处理部分没有触及太多。
当我在我的机器(win7)上本地测试我的服务时,它似乎运行良好,一切都很好。在Windows Server 2008上运行它时的情况相同。在Windows Server 2008上运行时,内存使用情况会在50k中徘徊(从任务管理器查看)。
当我在Windows Server 2003上运行该服务时,通过.net 4运行所有.net更新/补丁,我收到错误:
Safe handle has been closed
at System.Net.Sockets.Socket.AcceptAsync(SocketAsyncEventArgs e)
at SocketAsyncServer.SocketListener.StartAccept() in 289
at SocketAsyncServer.SocketListener.ProcessAccept(SocketAsyncEventArgs acceptEventArgs) 367
at SocketAsyncServer.SocketListener.AcceptEventArg_Completed(Object sender, SocketAsyncEventArgs e) in 326
at System.Net.Sockets.SocketAsyncEventArgs.OnCompleted(SocketAsyncEventArgs e)
at System.Net.Sockets.SocketAsyncEventArgs.ExecutionCallback(Object ignored)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Net.Sockets.SocketAsyncEventArgs.FinishOperationSuccess(SocketError socketError, Int32 bytesTransferred, SocketFlags flags)
at System.Net.Sockets.SocketAsyncEventArgs.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
与此相关的代码行是: 第326行
private void AcceptEventArg_Completed(object sender, SocketAsyncEventArgs e)
{
//Any code that you put in this method will NOT be called if
//the operation completes synchronously, which will probably happen when
//there is some kind of socket error. It might be better to put the code
//in the ProcessAccept method.
ProcessAccept(e);
}
第289行
bool willRaiseEvent = listenSocket.AcceptAsync(acceptEventArg);
此服务器正在连接到远程客户端以发送数据(小型遥测有效负载),我们在其中解析数据并发回响应,并在连接套接字时继续执行此操作。
我愿意接受建议或尝试的事情。另一个注意事项是,当我在win2k3上运行此服务时,mem使用天空火箭发射到600 + Kb而服务器2008上的50-60Kb范围,并抛出上述错误。
答案 0 :(得分:0)
我在示例中提供的链接中阅读了多页评论后发现了这个问题。
在SocketListener类中,有一个名为“HandleBadAccept”的方法,它是:
private void HandleBadAccept(SocketAsyncEventArgs acceptEventArgs)
{
var acceptOpToken = (acceptEventArgs.UserToken as AcceptOpUserToken);
//This method closes the socket and releases all resources, both
//managed and unmanaged. It internally calls Dispose.
acceptEventArgs.AcceptSocket.Close();
acceptEventArgs.AcceptSocket = null; //added to handle win2k3 issue
//Put the SAEA back in the pool.
poolOfAcceptEventArgs.Push(acceptEventArgs);
}
我不得不添加
acceptEventArgs.AcceptSocket = null;
现在在Windows 2003计算机上正常运行。