TcpClient close() method socket leak

  • Thread starter Thread starter Daniel
  • Start date Start date
D

Daniel

TcpClient close() method socket leak

when i use TcpClient to open a connection, send data and close the TcpClient
with myTcpClientInstance.Close(); it takes 60 seconds for the actual socket
on the client machine to close per my network app the computer fills up w/
thousands of these

[System Process]:0 TCP foobox:8888 localhost:2188 TIME_WAIT
[System Process]:0 TCP foobox:8888 localhost:2189 TIME_WAIT
[System Process]:0 TCP foobox:8888 localhost:2190 TIME_WAIT
[System Process]:0 TCP foobox:8888 localhost:2191 TIME_WAIT
[System Process]:0 TCP foobox:8888 localhost:2192 TIME_WAIT
[System Process]:0 TCP foobox:8888 localhost:2193 TIME_WAIT

until the "Only one usage of each socket address" error occures. How to
work around this? I need to open connect, send data, and close it. i can not
share connections in my case i have to open, send and close and have the
close truely close. and i have to do more then 3k of these in 60 seconds. I
know this is possible because I have a c version of the client that uses c
sockets and it works fine and does not fill with thousands of:

[System Process]:0 TCP foobox:8888 localhost:2188 TIME_WAIT

Is this a limitation of TcpClient ? or is there a way to truely close a
TcpClient imediatly? i tried setting linger option false, no delay true,
timeout 0 etc. still no progress the client sockets all get used up w/
thousands of

[System Process]:0 TCP foobox:8888 localhost:2188 TIME_WAIT
[System Process]:0 TCP foobox:8888 localhost:2189 TIME_WAIT
[System Process]:0 TCP foobox:8888 localhost:2190 TIME_WAIT

until the "Only one usage of each socket address" error occures.

here is what my client code looks like:

TcpClient myclient;
myclient = new TcpClient();
LingerOption lingerOption = new LingerOption (false, 0);
myclient.LingerState = lingerOption;
myclient.NoDelay = true;
myclient.ReceiveTimeout = 0;
myclient.Connect("foobox", 8888);
NetworkStream networkStream ;
networkStream = myclient.GetStream();
StreamWriter streamWriter ;
streamWriter = new StreamWriter(networkStream);
string strData = "";
strData += "helloworld\0";
streamWriter.WriteLine(strData);
streamWriter.Flush();
streamWriter.Close() ;
networkStream.Close();
myclient.Close();

something missing? should i do more then close? i tried shutdown too.. no
progress

here is the dummy server code if it matters:

public static void Main()
{
TcpListener tcpListener = new TcpListener(8082);
tcpListener.Start();
Console.WriteLine("Server Started") ;
while(true)
{
Socket socketForClient = tcpListener.AcceptSocket();
try
{
if(socketForClient.Connected)
{
Console.WriteLine("Client connected");
NetworkStream networkStream = new NetworkStream(socketForClient);
StreamReader streamReader = new StreamReader(networkStream);
string line = streamReader.ReadLine();
streamReader.Close();
Console.WriteLine("Read:" +line);
}
socketForClient.Shutdown(System.Net.Sockets.SocketShutdown.Both);
socketForClient.Close();
Console.WriteLine("Client disconnected");
GC.Collect();
Console.WriteLine("Garbage Collected");
}
catch(Exception e)
{
Console.WriteLine(e.ToString()) ;
}
}
}
 
Did you get any exceptions when running the code? If so, the Close()
method wouldn't have been called. I suggest using a "using" statement
and try again.

using (NetworkStream networkStream = new
NetworkStream(socketForClient))
{
// code
}
This makes sure that the stream and the client is closed even if there
is an exception
 
also, even after the client executable is unloaded from memory the ever evil
socket entries remain for 60 seconds:
[System Process]:0 TCP foobox:8888 localhost:2188 TIME_WAIT
[System Process]:0 TCP foobox:8888 localhost:2189 TIME_WAIT
[System Process]:0 TCP foobox:8888 localhost:2190 TIME_WAIT

is it that i can only do 3000 open, send, close in every 60 seconds per a
limitation w/ the TcpClient or is there something else i could try?
 
Daniel said:
TcpClient close() method socket leak

when i use TcpClient to open a connection, send data and close the
TcpClient
with myTcpClientInstance.Close(); it takes 60 seconds for the actual
socket
on the client machine to close per my network app the computer fills up w/
thousands of these

[System Process]:0 TCP foobox:8888 localhost:2188 TIME_WAIT
[System Process]:0 TCP foobox:8888 localhost:2189 TIME_WAIT

In my experience it's quite usual to see hundreds of these appearing when
opening and closing sockets quickly and I have never had a problem with it.
However, I have never tried to do quite so many in such a short period of
time.

Although I don't have experience of this specific area, my _guess_ would be
that the framework is trying to present a simplified interface to
programming TCP and perhaps hasn't exposed some detailed option that you
need to achieve this level of performance. If this turns out to be the case,
maybe you should use some unmanaged code for this specific function

Andy
 
Try setting DontLinger on the socket per
http://msdn.microsoft.com/library/d...ystemnetsocketssocketoptionnameclasstopic.asp

You can do this by either accessing the underlying socket directly (.Client)
or by using TcpClient's LingerState:
http://msdn.microsoft.com/library/d...mnetsocketstcpclientclasslingerstatetopic.asp

Daniel said:
TcpClient close() method socket leak

when i use TcpClient to open a connection, send data and close the TcpClient
with myTcpClientInstance.Close(); it takes 60 seconds for the actual socket
on the client machine to close per my network app the computer fills up w/
thousands of these

[System Process]:0 TCP foobox:8888 localhost:2188 TIME_WAIT
[System Process]:0 TCP foobox:8888 localhost:2189 TIME_WAIT
[System Process]:0 TCP foobox:8888 localhost:2190 TIME_WAIT
[System Process]:0 TCP foobox:8888 localhost:2191 TIME_WAIT
[System Process]:0 TCP foobox:8888 localhost:2192 TIME_WAIT
[System Process]:0 TCP foobox:8888 localhost:2193 TIME_WAIT

until the "Only one usage of each socket address" error occures. How to
work around this? I need to open connect, send data, and close it. i can not
share connections in my case i have to open, send and close and have the
close truely close. and i have to do more then 3k of these in 60 seconds. I
know this is possible because I have a c version of the client that uses c
sockets and it works fine and does not fill with thousands of:

[System Process]:0 TCP foobox:8888 localhost:2188 TIME_WAIT

Is this a limitation of TcpClient ? or is there a way to truely close a
TcpClient imediatly? i tried setting linger option false, no delay true,
timeout 0 etc. still no progress the client sockets all get used up w/
thousands of

[System Process]:0 TCP foobox:8888 localhost:2188 TIME_WAIT
[System Process]:0 TCP foobox:8888 localhost:2189 TIME_WAIT
[System Process]:0 TCP foobox:8888 localhost:2190 TIME_WAIT

until the "Only one usage of each socket address" error occures.

here is what my client code looks like:

TcpClient myclient;
myclient = new TcpClient();
LingerOption lingerOption = new LingerOption (false, 0);
myclient.LingerState = lingerOption;
myclient.NoDelay = true;
myclient.ReceiveTimeout = 0;
myclient.Connect("foobox", 8888);
NetworkStream networkStream ;
networkStream = myclient.GetStream();
StreamWriter streamWriter ;
streamWriter = new StreamWriter(networkStream);
string strData = "";
strData += "helloworld\0";
streamWriter.WriteLine(strData);
streamWriter.Flush();
streamWriter.Close() ;
networkStream.Close();
myclient.Close();

something missing? should i do more then close? i tried shutdown too.. no
progress

here is the dummy server code if it matters:

public static void Main()
{
TcpListener tcpListener = new TcpListener(8082);
tcpListener.Start();
Console.WriteLine("Server Started") ;
while(true)
{
Socket socketForClient = tcpListener.AcceptSocket();
try
{
if(socketForClient.Connected)
{
Console.WriteLine("Client connected");
NetworkStream networkStream = new NetworkStream(socketForClient);
StreamReader streamReader = new StreamReader(networkStream);
string line = streamReader.ReadLine();
streamReader.Close();
Console.WriteLine("Read:" +line);
}
socketForClient.Shutdown(System.Net.Sockets.SocketShutdown.Both);
socketForClient.Close();
Console.WriteLine("Client disconnected");
GC.Collect();
Console.WriteLine("Garbage Collected");
}
catch(Exception e)
{
Console.WriteLine(e.ToString()) ;
}
}
}
 
Back
Top