Search code examples
c#socketsexception

Error "The I/O operation has been aborted because of either a thread exit or an application request"


My application is working as a client application for a bank server. The application is sending a request and getting a response from the bank. This application is normally working fine, but sometimes

The I/O operation has been aborted because of either a thread exit or an application request

error with error code as 995 (0x3E3) comes through.

public void OnDataReceived(IAsyncResult asyn)
{
    BLCommonFunctions.WriteLogger(
        0,
        "In: OnDataReceived",
        ref swReceivedLogWriter, 
        strLogPath, 
        0);
    try
    {
        SocketPacket theSockId = (SocketPacket)asyn.AsyncState;

        int iRx = theSockId.thisSocket.EndReceive(asyn); // Here the error is coming
        string strHEX = BLCommonFunctions.ByteArrToHex(theSockId.dataBuffer);
    }
}

Once this error starts to come for all transactions after that same error begin to appear, so how can I sort out this problem?

If possible then with some sample code.


Solution

  • 995 is an error reported by the I/O Completion Port. The error comes since you try to continue read from the socket when it has most likely been closed.

    Receiving 0 bytes from EndRecieve means that the socket has been closed, as does most exceptions that EndRecieve will throw.

    You need to start dealing with those situations.

    Never ever ignore exceptions. They are thrown for a reason.

    There is nothing that says that the server does anything wrong. A connection can be lost for a lot of reasons, such as an idle connection being closed by a switch/router/firewall, shaky network, bad cables, etc.

    I'm saying that you must handle disconnections. The proper way of doing so is to dispose the socket and try to connect a new one at certain intervals.

    As for the receive callback a more proper way of handling it is something like this (semi pseudo code):

    public void OnDataReceived(IAsyncResult asyn)
    {
        BLCommonFunctions.WriteLogger(
            0,
            "In: OnDataReceived",
            ref swReceivedLogWriter,
            strLogPath,
            0);
        try
        {
            SocketPacket client = (SocketPacket)asyn.AsyncState;
    
            int bytesReceived = client.thisSocket.EndReceive(asyn); // Here the error is coming
            if (bytesReceived == 0)
            {
              HandleDisconnect(client);
              return;
            }
        }
        catch (Exception err)
        {
           HandleDisconnect(client);
        }
    
        try
        {
            string strHEX = BLCommonFunctions.ByteArrToHex(theSockId.dataBuffer);
    
            // Do your handling here
        }
        catch (Exception err)
        {
            // Your logic threw an exception. handle it accordinhly
        }
    
        try
        {
           client.thisSocket.BeginRecieve(.. all parameters ..);
        }
        catch (Exception err)
        {
           HandleDisconnect(client);
        }
    }
    

    The reason to why I'm using three catch blocks is simply because the logic for the middle one is different from the other two. Exceptions from BeginReceive/EndReceive usually indicates socket disconnection while exceptions from your logic should not stop the socket receiving.