A non-blocking socket operation could not be completed

There is a bug in .NET 2.0 regarding timeout handling by Socket class.
Here’s the code that reproduces this behavior.

using(TcpClient client = new TcpClient())
{
    // Set timeout
    client.ReceiveTimeout =
        (int)TimeSpan.FromSeconds(1).TotalMilliseconds;

    // Connect to perfectly working imap server
    client.Connect("mail.limilabs.com", 143);

    // Create reader and writer
    NetworkStream stream = client.GetStream();
    StreamReader reader = new StreamReader(stream);
    StreamWriter writer = new StreamWriter(stream);

    // Read hello line
    Console.WriteLine(reader.ReadLine());

    // this works with no problems
    writer.WriteLine("a NOOP");             // No operation command
    writer.Flush();
    Console.WriteLine(reader.ReadLine());   // No operation response

    try
    {
        reader.ReadLine();                  // Nothing to read
    }
    catch (Exception ex)                    // Timeout
    {
        Console.WriteLine("timeout");       // This is expected
    }

    writer.WriteLine("b NOOP");             // No operation command
    writer.Flush();

    // SocketException: A non-blocking socket operation
    // could not be completed immediately
    Console.WriteLine(reader.ReadLine());

    client.Close();
}

The above code runs as expected on Mono and on .NET 4.0.

The problem is in UpdateStatusAfterSocketError internal Socket method that executes SetToDisconnected method when any exception is thrown, including timeout exception.

Tags:  

Questions?

Consider using our Q&A forum for asking questions.

2 Responses to “A non-blocking socket operation could not be completed”

  1. John T. Angle Says:

    Try resetting Blocking property before each of your reader.ReadLine() statements. In C# that is “client.Blocking = true;”, I’m not sure what it is in VB.

    We had same problem in .NET3.5 which *seems* to have been resolved with this approach.

  2. Kalasu Says:

    Hai,
    Thanks for your reply,But i am not using the TcpClient Channel,i am only using the Tcp Channel..in my client side i only registered my client for example
    if (_clientChannel == null)
    {
    //Create the channel
    _clientChannel = new TcpChannel();
    //Register the channel

    ChannelServices.RegisterChannel(_clientChannel, false);

    }
    //Create a proxy object to access the remote File
    objTest =
    (Test)Activator.GetObject(typeof(Test),
    ipAddr);

    so please give the suggestion where i use the socket code inside my program