Question

I haven't been able to find much on this topic, but recently I've been implementing a socket server using the SocketAsyncEventArgs objects. I followed the example from: Code Project Example

I modified the data handling classes to fit my needs, and didn't touch much if any of the socket handling portion.

When I test my service locally on my machine (win7), it appears to run fine, all is well. Same story when running it on windows server 2008. When running on windows server 2008, the mem usage hovers in the 50k's (viewing from task manager).

When I run the service on windows server 2003, that has all the .net updates/patches through .net 4, I get an error:

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)

the lines of code this relates to are: line 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);
}

line 289

bool willRaiseEvent = listenSocket.AcceptAsync(acceptEventArg);

This server is contantly being connected to from remote clients to send data (small telemetry payloads), in which we parse the data and send a response back, and continue this while the socket is connected.

I'm open to suggestions or things to try. Another note is when I run this service on win2k3, the mem usage sky rockets to 600+Kb vs. the 50-60Kb range on server 2008 and the error above is thrown.

Was it helpful?

Solution

I found the issue after reading multiple pages of comments in the link provided to the example.

In the SocketListener class, there is a method called "HandleBadAccept" which is:

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

I had to add the

acceptEventArgs.AcceptSocket = null;

this is now running fine on a windows 2003 machine.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top