Search code examples
c#tcptcpclientthread-sleep

TcpClient.Close() works only with Thread.Sleep()


I have simple server that gets string from client and prints it on screen. I also have simple client, sending data and closing:

static void Main()
{
        var client = new TcpClient("localhost", 26140);

        var stream = client.GetStream();
        Byte[] data = System.Text.Encoding.UTF8.GetBytes("CALC qwer"); 
        stream.Write(data, 0, data.Length);
        stream.Close();
        client.Close();
        //Thread.Sleep(100);
}

And with uncommented string 'Thread.Sleep(100)' it works ok. But when commenting, sometimes ( 1 of 5-10 runs ) client doesn't send the string. Watching wireshark and netstat I've noticed that client sends SYN,ACK package, establishes connection and exits without sending anything and without closing the socket.

Could anyone explain this behaivor? Why sleep helps? What am I doing wrong?

UPD:

With this sample code adding flush() before closing really works, thanks Fox32.

But after it I returned to my initial code:

var client = new TcpClient("localhost", 26140);
client.NoDelay = true;
var stream = client.GetStream();
var writer = new StreamWriter(stream);
writer.WriteLine("CALC qwer");
writer.Flush();
stream.Flush();
stream.Close();
client.Close();

And it isn't working, even with NoDelay. It's bad - using StreamWriter over network stream?

UPD:

Here is server code:

static void Main(string[] args)
    {
        (new Server(26140)).Run();
    }

In Server class:

public void Run()
    {
        var listener = new TcpListener(IPAddress.Any, port);
        listener.Start();
        while (true)
        {
            try
            {
                var client = listener.AcceptTcpClient();
                Console.WriteLine("Client accepted: " + client.Client.RemoteEndPoint);
                var stream = client.GetStream();
                stream.ReadTimeout = 2000;
                byte[] buffer = new byte[1000];
                stream.Read(buffer, 0, 1000);
                var s = Encoding.UTF8.GetString(buffer);
                Console.WriteLine(s);
            }
            catch (Exception ex)
            {
                Console.WriteLine("ERROR! " + ex.Message);
            }
        }
    }

UPD:

Adding even Sleep(1) makes crashes happen in 1 of 30-50 clients running at the same time. And adding Sleep(10) seems to be solving it totally, I can't catch any crash. Don't understand, why socket needs this several milliseconds to close correctly.


Solution

  • I've tried code, reproducing this bug on several computers. No one crashes. Seems like it's my local computer bug.

    Thanks for everybody for trying to help me.

    Anyway, it's so strange. If I'll found out why this bug exists on my computer, I'll write about it.