Socket dont really close. Please help microsoft MVP!

  • Thread starter Nicholas Paldino [.NET/C# MVP]
  • Start date
N

Nicholas Paldino [.NET/C# MVP]

AA,

I found the following in an article about SQL server and connecting to
it:

Note that the SQL Server network library specifically does not enable the
SO_REUSEADDR TCP/IP socket option for security reasons. When SO_REUSEADDR is
enabled, a malicious user can hijack a client port to SQL Server and use the
credentials that the client supplies to gain access to the computer that is
running SQL Server. By default, because the SQL Server network library does
not enable the SO_REUSEADDR socket option, every time you open and close a
socket through the SQL Server network library on the client side, the socket
enters a TIME_WAIT state for four minutes. If you are rapidly opening and
closing SQL Server connections over TCP/IP with pooling disabled, you are
rapidly opening and closing TCP/IP sockets. In other words, each SQL Server
connection has one TCP/IP socket. If you rapidly open and close 4000 sockets
in less than four minutes, you will reach the default maximum setting for
client anonymous ports, and new socket connection attempts fail until the
existing set of TIME_WAIT sockets times out.

While you are not using SQL server, it is the same problem you are
having. What you can do is set the following value in the registry:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpTim
edWaitDelay

You can set the value to the number of seconds to wait before the socket
is usable again.

However, setting this can have detrimental effects. Is there a need to
open a few thousand client connections? Can it be done a different, and
more efficient way? Setting the above value is dangerous because it is
machine-wide.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- nick(dot)paldino=at=exisconsulting<dot>com

AA said:
This is making me crazy!!

Please, if some body can help me.

I'm testing a ver simple socket client.
In my test I just open and close a connection (in a loop) to my local IIS
server (port 80)

using System.Net.Sockets;

for (int I = 0; I < 5000; I++)
{
TcpClient myClient = new TcpClient();
try
{
myClient.Connect("127.0.0.1", 80)
}
catch (Exception ex) {MessangeBox.Show(ex.ToString()); }
myClient.Close()
} //End for


Everything go fine, thousands of connections are opened and closed until
this error appear....

[ System.Net.Sockets.SocketException: Only one usage of each socket address
(protocol/network address/port) is normally permitted ]

After this error, I execute the netstat -a command and the lines (below)
appear thousands of times, lines below are just a very little part of the
complete list.

TCP asusis-dsgn:3505 localhost:80 TIME_WAIT
TCP asusis-dsgn:3506 localhost:80 TIME_WAIT
TCP asusis-dsgn:3507 localhost:89 TIME_WAIT
TCP asusis-dsgn:3508 localhost:89 TIME_WAIT
TCP asusis-dsgn:3509 localhost:89 TIME_WAIT
TCP asusis-dsgn:3510 localhost:89 TIME_WAIT
TCP asusis-dsgn:3511 localhost:89 TIME_WAIT
TCP asusis-dsgn:3512 localhost:89 TIME_WAIT
TCP asusis-dsgn:3513 localhost:89 TIME_WAIT
TCP asusis-dsgn:3514 localhost:89 TIME_WAIT
TCP asusis-dsgn:3515 localhost:89 TIME_WAIT
TCP asusis-dsgn:3516 localhost:89 TIME_WAIT
TCP asusis-dsgn:3517 localhost:89 TIME_WAIT
TCP asusis-dsgn:3518 localhost:89 TIME_WAIT
TCP asusis-dsgn:3519 localhost:89 TIME_WAIT
TCP asusis-dsgn:3520 localhost:89 TIME_WAIT
TCP asusis-dsgn:3521 localhost:89 TIME_WAIT
TCP asusis-dsgn:3522 localhost:89 TIME_WAIT
TCP asusis-dsgn:3523 localhost:89 TIME_WAIT
TCP asusis-dsgn:3524 localhost:89 TIME_WAIT
TCP asusis-dsgn:3525 localhost:89 TIME_WAIT
TCP asusis-dsgn:3526 localhost:89 TIME_WAIT
TCP asusis-dsgn:3527 localhost:89 TIME_WAIT

I think that for some reason the .net framework is not really closing the
socket, so it still alive with the TIME_WAIT status

And after thousands of TIME_WAIT connections, the OS reject connections.

Pleaseeeeee help to solve it!!


Thanks
 
A

AA

This is making me crazy!!

Please, if some body can help me.

I'm testing a ver simple socket client.
In my test I just open and close a connection (in a loop) to my local IIS
server (port 80)

using System.Net.Sockets;

for (int I = 0; I < 5000; I++)
{
TcpClient myClient = new TcpClient();
try
{
myClient.Connect("127.0.0.1", 80)
}
catch (Exception ex) {MessangeBox.Show(ex.ToString()); }
myClient.Close()
} //End for


Everything go fine, thousands of connections are opened and closed until
this error appear....

[ System.Net.Sockets.SocketException: Only one usage of each socket address
(protocol/network address/port) is normally permitted ]

After this error, I execute the netstat -a command and the lines (below)
appear thousands of times, lines below are just a very little part of the
complete list.

TCP asusis-dsgn:3505 localhost:80 TIME_WAIT
TCP asusis-dsgn:3506 localhost:80 TIME_WAIT
TCP asusis-dsgn:3507 localhost:89 TIME_WAIT
TCP asusis-dsgn:3508 localhost:89 TIME_WAIT
TCP asusis-dsgn:3509 localhost:89 TIME_WAIT
TCP asusis-dsgn:3510 localhost:89 TIME_WAIT
TCP asusis-dsgn:3511 localhost:89 TIME_WAIT
TCP asusis-dsgn:3512 localhost:89 TIME_WAIT
TCP asusis-dsgn:3513 localhost:89 TIME_WAIT
TCP asusis-dsgn:3514 localhost:89 TIME_WAIT
TCP asusis-dsgn:3515 localhost:89 TIME_WAIT
TCP asusis-dsgn:3516 localhost:89 TIME_WAIT
TCP asusis-dsgn:3517 localhost:89 TIME_WAIT
TCP asusis-dsgn:3518 localhost:89 TIME_WAIT
TCP asusis-dsgn:3519 localhost:89 TIME_WAIT
TCP asusis-dsgn:3520 localhost:89 TIME_WAIT
TCP asusis-dsgn:3521 localhost:89 TIME_WAIT
TCP asusis-dsgn:3522 localhost:89 TIME_WAIT
TCP asusis-dsgn:3523 localhost:89 TIME_WAIT
TCP asusis-dsgn:3524 localhost:89 TIME_WAIT
TCP asusis-dsgn:3525 localhost:89 TIME_WAIT
TCP asusis-dsgn:3526 localhost:89 TIME_WAIT
TCP asusis-dsgn:3527 localhost:89 TIME_WAIT

I think that for some reason the .net framework is not really closing the
socket, so it still alive with the TIME_WAIT status

And after thousands of TIME_WAIT connections, the OS reject connections.

Pleaseeeeee help to solve it!!


Thanks
 
A

AA

Excellent.

Thank you very much Nicholas, this is the explain that I was searched for
long time.

AA


Nicholas Paldino said:
AA,

I found the following in an article about SQL server and connecting to
it:

Note that the SQL Server network library specifically does not enable the
SO_REUSEADDR TCP/IP socket option for security reasons. When SO_REUSEADDR is
enabled, a malicious user can hijack a client port to SQL Server and use the
credentials that the client supplies to gain access to the computer that is
running SQL Server. By default, because the SQL Server network library does
not enable the SO_REUSEADDR socket option, every time you open and close a
socket through the SQL Server network library on the client side, the socket
enters a TIME_WAIT state for four minutes. If you are rapidly opening and
closing SQL Server connections over TCP/IP with pooling disabled, you are
rapidly opening and closing TCP/IP sockets. In other words, each SQL Server
connection has one TCP/IP socket. If you rapidly open and close 4000 sockets
in less than four minutes, you will reach the default maximum setting for
client anonymous ports, and new socket connection attempts fail until the
existing set of TIME_WAIT sockets times out.

While you are not using SQL server, it is the same problem you are
having. What you can do is set the following value in the registry:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpTim
edWaitDelay

You can set the value to the number of seconds to wait before the socket
is usable again.

However, setting this can have detrimental effects. Is there a need to
open a few thousand client connections? Can it be done a different, and
more efficient way? Setting the above value is dangerous because it is
machine-wide.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- nick(dot)paldino=at=exisconsulting<dot>com

AA said:
This is making me crazy!!

Please, if some body can help me.

I'm testing a ver simple socket client.
In my test I just open and close a connection (in a loop) to my local IIS
server (port 80)

using System.Net.Sockets;

for (int I = 0; I < 5000; I++)
{
TcpClient myClient = new TcpClient();
try
{
myClient.Connect("127.0.0.1", 80)
}
catch (Exception ex) {MessangeBox.Show(ex.ToString()); }
myClient.Close()
} //End for


Everything go fine, thousands of connections are opened and closed until
this error appear....

[ System.Net.Sockets.SocketException: Only one usage of each socket address
(protocol/network address/port) is normally permitted ]

After this error, I execute the netstat -a command and the lines (below)
appear thousands of times, lines below are just a very little part of the
complete list.

TCP asusis-dsgn:3505 localhost:80 TIME_WAIT
TCP asusis-dsgn:3506 localhost:80 TIME_WAIT
TCP asusis-dsgn:3507 localhost:89 TIME_WAIT
TCP asusis-dsgn:3508 localhost:89 TIME_WAIT
TCP asusis-dsgn:3509 localhost:89 TIME_WAIT
TCP asusis-dsgn:3510 localhost:89 TIME_WAIT
TCP asusis-dsgn:3511 localhost:89 TIME_WAIT
TCP asusis-dsgn:3512 localhost:89 TIME_WAIT
TCP asusis-dsgn:3513 localhost:89 TIME_WAIT
TCP asusis-dsgn:3514 localhost:89 TIME_WAIT
TCP asusis-dsgn:3515 localhost:89 TIME_WAIT
TCP asusis-dsgn:3516 localhost:89 TIME_WAIT
TCP asusis-dsgn:3517 localhost:89 TIME_WAIT
TCP asusis-dsgn:3518 localhost:89 TIME_WAIT
TCP asusis-dsgn:3519 localhost:89 TIME_WAIT
TCP asusis-dsgn:3520 localhost:89 TIME_WAIT
TCP asusis-dsgn:3521 localhost:89 TIME_WAIT
TCP asusis-dsgn:3522 localhost:89 TIME_WAIT
TCP asusis-dsgn:3523 localhost:89 TIME_WAIT
TCP asusis-dsgn:3524 localhost:89 TIME_WAIT
TCP asusis-dsgn:3525 localhost:89 TIME_WAIT
TCP asusis-dsgn:3526 localhost:89 TIME_WAIT
TCP asusis-dsgn:3527 localhost:89 TIME_WAIT

I think that for some reason the .net framework is not really closing the
socket, so it still alive with the TIME_WAIT status

And after thousands of TIME_WAIT connections, the OS reject connections.

Pleaseeeeee help to solve it!!


Thanks
 
A

AA

Another question.. Is possible that, programatically (in .NET) to set this
property? Not for all applications, for a specific application that I want?

Because, When I use the Microsoft Application Center Test, I look that he
open and close thousands of connection, but when i execute the netstat I saw
just 1 record

It will be excellent for me

Thanks a lot

AA


Nicholas Paldino said:
AA,

I found the following in an article about SQL server and connecting to
it:

Note that the SQL Server network library specifically does not enable the
SO_REUSEADDR TCP/IP socket option for security reasons. When SO_REUSEADDR is
enabled, a malicious user can hijack a client port to SQL Server and use the
credentials that the client supplies to gain access to the computer that is
running SQL Server. By default, because the SQL Server network library does
not enable the SO_REUSEADDR socket option, every time you open and close a
socket through the SQL Server network library on the client side, the socket
enters a TIME_WAIT state for four minutes. If you are rapidly opening and
closing SQL Server connections over TCP/IP with pooling disabled, you are
rapidly opening and closing TCP/IP sockets. In other words, each SQL Server
connection has one TCP/IP socket. If you rapidly open and close 4000 sockets
in less than four minutes, you will reach the default maximum setting for
client anonymous ports, and new socket connection attempts fail until the
existing set of TIME_WAIT sockets times out.

While you are not using SQL server, it is the same problem you are
having. What you can do is set the following value in the registry:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpTim
edWaitDelay

You can set the value to the number of seconds to wait before the socket
is usable again.

However, setting this can have detrimental effects. Is there a need to
open a few thousand client connections? Can it be done a different, and
more efficient way? Setting the above value is dangerous because it is
machine-wide.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- nick(dot)paldino=at=exisconsulting<dot>com

AA said:
This is making me crazy!!

Please, if some body can help me.

I'm testing a ver simple socket client.
In my test I just open and close a connection (in a loop) to my local IIS
server (port 80)

using System.Net.Sockets;

for (int I = 0; I < 5000; I++)
{
TcpClient myClient = new TcpClient();
try
{
myClient.Connect("127.0.0.1", 80)
}
catch (Exception ex) {MessangeBox.Show(ex.ToString()); }
myClient.Close()
} //End for


Everything go fine, thousands of connections are opened and closed until
this error appear....

[ System.Net.Sockets.SocketException: Only one usage of each socket address
(protocol/network address/port) is normally permitted ]

After this error, I execute the netstat -a command and the lines (below)
appear thousands of times, lines below are just a very little part of the
complete list.

TCP asusis-dsgn:3505 localhost:80 TIME_WAIT
TCP asusis-dsgn:3506 localhost:80 TIME_WAIT
TCP asusis-dsgn:3507 localhost:89 TIME_WAIT
TCP asusis-dsgn:3508 localhost:89 TIME_WAIT
TCP asusis-dsgn:3509 localhost:89 TIME_WAIT
TCP asusis-dsgn:3510 localhost:89 TIME_WAIT
TCP asusis-dsgn:3511 localhost:89 TIME_WAIT
TCP asusis-dsgn:3512 localhost:89 TIME_WAIT
TCP asusis-dsgn:3513 localhost:89 TIME_WAIT
TCP asusis-dsgn:3514 localhost:89 TIME_WAIT
TCP asusis-dsgn:3515 localhost:89 TIME_WAIT
TCP asusis-dsgn:3516 localhost:89 TIME_WAIT
TCP asusis-dsgn:3517 localhost:89 TIME_WAIT
TCP asusis-dsgn:3518 localhost:89 TIME_WAIT
TCP asusis-dsgn:3519 localhost:89 TIME_WAIT
TCP asusis-dsgn:3520 localhost:89 TIME_WAIT
TCP asusis-dsgn:3521 localhost:89 TIME_WAIT
TCP asusis-dsgn:3522 localhost:89 TIME_WAIT
TCP asusis-dsgn:3523 localhost:89 TIME_WAIT
TCP asusis-dsgn:3524 localhost:89 TIME_WAIT
TCP asusis-dsgn:3525 localhost:89 TIME_WAIT
TCP asusis-dsgn:3526 localhost:89 TIME_WAIT
TCP asusis-dsgn:3527 localhost:89 TIME_WAIT

I think that for some reason the .net framework is not really closing the
socket, so it still alive with the TIME_WAIT status

And after thousands of TIME_WAIT connections, the OS reject connections.

Pleaseeeeee help to solve it!!


Thanks
 
S

Stu Banter

[snap]
While you are not using SQL server, it is the same problem you are
having. What you can do is set the following value in the registry:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpTim
edWaitDelay
You can set the value to the number of seconds to wait before the socket
is usable again.

With respect for the workaround, this is the typical kind of quick fix I
think often introduces perhaps more misery than it fixes. It's kind of hard
to swallow it is NOT possible to close the connection from the calling
class. Regardless of whether it's a best practice approach, isn't at least
STRANGE the connection can not be closed by the process initiating it ?

Don't get me wrong, I am not arguing your probably perfectlly valid
solution, I just think it is a bit typical of how Windows programs are often
quite unstable and/or disrupt other programs' execution. The term
end-of-pipe-solution comes to mind...

Best!,
Stu
 
A

Alan Pretre

AA said:
I'm testing a ver simple socket client.
In my test I just open and close a connection (in a loop) to my local IIS
server (port 80)

using System.Net.Sockets;

for (int I = 0; I < 5000; I++)
{
TcpClient myClient = new TcpClient();
try
{
myClient.Connect("127.0.0.1", 80)
}
catch (Exception ex) {MessangeBox.Show(ex.ToString()); }
myClient.Close()
} //End for


Everything go fine, thousands of connections are opened and closed until
this error appear....

[ System.Net.Sockets.SocketException: Only one usage of each socket address
(protocol/network address/port) is normally permitted ]
I think that for some reason the .net framework is not really closing the
socket, so it still alive with the TIME_WAIT status

And after thousands of TIME_WAIT connections, the OS reject connections.


I think your problem is that you should also be closing the underlying
stream:

for (int i = 0; i < 5000; i++) {
TcpClient myClient = new TcpClient();
try {
myClient.Connect("127.0.0.1", 80)
} catch (Exception ex) {
MessageBox.Show(ex.ToString());
} finally {

if (myClient.GetStream() != null) myClient.GetStream().Close(); //
Does a Dispose().
myClient.Close(); // Does a Dispose().
}
}


-- Alan
 
J

Jon Skeet [C# MVP]

Alan Pretre said:
I think your problem is that you should also be closing the underlying
stream:

<snip>

I don't think so. From the docs for TcpClient.Close():

<quote>
The Close method closes the TCP connection. It calls the Dispose method
passing a true value to release all managed and unmanaged resources
associated with the TcpClient. These resources include the underlying
Socket used for connecting with the remote host, and the NetworkStream
used to send and receive data.
</quote>

I think it's actually perfectly natural - when a connection is closed,
it *does* go into TIME_WAIT. I think everything's behaving fine here,
although I'll admit to not understanding the real details of TCP/IP as
well as I'd like. See
http://www.developerweb.net/sock-faq/detail.php?id=13
for more details.
 
A

Alan Pretre

Jon Skeet said:
I don't think so. From the docs for TcpClient.Close():

<quote>
The Close method closes the TCP connection. It calls the Dispose method
passing a true value to release all managed and unmanaged resources
associated with the TcpClient. These resources include the underlying
Socket used for connecting with the remote host, and the NetworkStream
used to send and receive data.
</quote>

I've seen this firsthand in my own code. You would like to think that
myClient.Close() is sufficient but it isn't. I don't know why. Perhaps
this is a bug?

See also, for example:
http://groups.google.com/groups?hl=...c2f9ec%24eab69eb0%24a301280a%40phx.gbl&rnum=3

-- Alan
 
J

Jon Skeet [C# MVP]

Alan Pretre said:
I've seen this firsthand in my own code. You would like to think that
myClient.Close() is sufficient but it isn't. I don't know why. Perhaps
this is a bug?

It certainly sounds like it. I wonder whether it closes the stream *if*
you've fetched it, but doesn't do everything necessary if you haven't
used the stream at all...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top