.NET socket lock processing timeout

To control the client connection, an instance of TcpClient created using the Accept method is used. The problem occurs when I need to stop the server flow, because it is blocked when receiving a call.

So, I'm setting up TcpClient ReceiveTimeout to loop every n milliseconds to check the exit condition. As a result, the Receive operation throws an exception (SocketException) with the error code SocketError.TimedOut. Ok, I thought ...

The problem is that the Socket.Connected property returns false, but as stated in the MSDN documentation:

The value of the Connected property reflects the state of the connection with the most recent operation. If you need to determine the current state of the connection, make a non-blocking, zero byte call. If the call returns successfully or generates an WAEWOULDBLOCK error code (10035), then the socket is still connected; otherwise, the socket is no longer connected.

So, I am doing what states:

try {
     // Receive operation on socket stream
     // Send operation on socket stream
} catch (SocketException e) {
    if (e.SocketErrorCode == SocketError.TimedOut) {
    try {
        IAsyncResult asyncResult;
        int sResult;

        asyncResult = mSocket.Client.BeginSend(new byte[] {}, 0, 0, SocketFlags.None, delegate(IAsyncResult result) { }, null);
        sResult = mSocket.Client.EndSend(asyncResult);
        Debug.Assert(asyncResult.IsCompleted == true);

        if (mSocket.Connected == false)
            throw new Exception("not more connected");  // Always thrown
    } catch (Exception e) {
             // ...
        }
}

But even if the aynch Send operation is performed, the mSocket.Connected property is always false, resulting in the external loop terminating (other threads call the Disconnect method to terminate the server thread).

What am I missing?

+3
source share
3 answers

, , TcpClient . , . async / select.

, async :

byte[] data = new byte[4096];
IASyncResult result = stream.BeginRead(data, 0, data.Length, null, null);
result.AsyncWaitHandle.WaitOne(<timeout value in ms>);
int bytes = stream.EndRead(result);

if (!result.IsCompleted)
  <timed out>
else
  <read data>
...
+2

:

+1

# Socket.Connected, . , .

// .Connect throws an exception if unsuccessful
client.Connect(anEndPoint);

// This is how you can determine whether a socket is still connected.
bool blockingState = client.Blocking;
try
{
    byte [] tmp = new byte[1];

    client.Blocking = false;
    client.Send(tmp, 0, 0);
    Console.WriteLine("Connected!");
}
catch (SocketException e) 
{
    // 10035 == WSAEWOULDBLOCK
    if (e.NativeErrorCode.Equals(10035))
        Console.WriteLine("Still Connected, but the Send would block");
    else
    {
        Console.WriteLine("Disconnected: error code {0}!", e.NativeErrorCode);
    }
}
finally
{
    client.Blocking = blockingState;
}

Console.WriteLine("Connected: {0}", client.Connected);
0

Source: https://habr.com/ru/post/1761714/


All Articles