0
votes

I have strange error in my app: "Only one usage of each socket" address.I saw many sockets in CLOSE_WAIT status in the tcpview. and I set linger timeout. but it doesn work. code below server:

TcpListener listener = new TcpListener(IPAddress.Any, 7874);
TcpClient client;
listener.Start();

while (true) 
{
    client = listener.AcceptTcpClient();
    ThreadPool.QueueUserWorkItem(ThreadProc, client);
}


private static void ThreadProc(object obj)
{
    var client = (TcpClient)obj;
    client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, new LingerOption(true, 0));
    var stream = client.GetStream();
    using(client){
        using (MemoryStream ms = new MemoryStream())
        {
            int numBytesRead;
            byte[] data = new byte[1024];
            try
            {
                while ((numBytesRead = stream.Read(data, 0, data.Length)) > 0)
                {
                    ms.Write(data, 0, numBytesRead);
                }
            }catch(Exception ex)
            {}
            var str = Encoding.ASCII.GetString(ms.ToArray(), 0, (int)ms.Length);

        }
    }
}

client:

while (true)
{
    try
    {

        using (TcpClient client = new TcpClient(obj.ToString(), 7874))

        {
            client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, new LingerOption(true, 0));
            var stream = client.GetStream();
            {
                stream.Write(bytes, 0, bytes.Length);

            }

            Thread.Sleep(timeSleep);
            //just trying all possible close
            client.Client.Shutdown(SocketShutdown.Both);
            client.Client.Close(0);
            client.Close();
        }
    }catch(Exception ex)
    {
        Console.WriteLine(ex);
    }
}

but python client work normally:

while True:
    s = socket.socket(
        socket.AF_INET, socket.SOCK_STREAM)
    try:
        s.connect((addr, 7874))
        l_onoff = 1
        l_linger = 0
        s.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER,
                     struct.pack('ii', l_onoff, l_linger))
        s.send(b'test')
        while True:
            data =s.recv(1024)
            break
    except Exception as ex:
        print(str(datetime.datetime.now())+'NS FAIL')
    finally:
        s.close()

looks like .NET tcpclient ignore set linger option. same result with:

client.LingerState = new LingerOption(true, 0);
1
Without a good minimal reproducible example reliably reproducing the problem, impossible to provide a good answer. That said, the code you did post appears to suffer from your neglecting to perform a true graceful shutdown. It's not sufficient to just call Shutdown(). Each endpoint needs to receive from the connection until the receive returns 0 byte count, to ensure it's received 100% of the data sent. Without this, the network layer has to keep the socket open for awhile. Note that when done correctly, you don't need the LINGER option.Peter Duniho
all this code "client.Client.Shutdown(SocketShutdown.Both); client.Client.Close(0); client.Close();" just for test. standard dispose produce same problem. network layer always leave socket in CLOSE_WAIT for liner timeout time during heavy loading. my question is: why .net ignore linger timeout. c++/python works normally. problem in .net onlykain64b

1 Answers

0
votes

I dont think you need set the LingerOption. My guess is that you do not dispose the client socket on server side (the accepted client), and then it keeps allocated in the socket stack.