473,326 Members | 2,133 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,326 software developers and data experts.

Closing a C# socket does not release port

I have a socket configured as TCP and running as a listener. When I
close socket, it doesn't always free up the port immediately. Even
when no connections have been made to it. So when I open the socket
again, the bind fails because the port is still in use. When I
execute the code in "debug" mode, the problem never occurs. When I
execute the same code in release mode, the problem appears about 20%
of the time.

Here's the code:

protected Socket socket = null;

public void Open()
{
socket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);

socket.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.DontLinger,
true);

IPEndPoint endPoint = new IPEndPoint(
System.Net.IPAddress.Parse(socketConfig.Address),
socketConfig.Port);

socket.Bind(endPoint);
socket.Listen(MAX_NUM_CONNECTIONS);

serverConnectThread = new Thread(ServerConnectThread);
serverConnectThread.Start();
}

public void Close()
{
socket.Close();
socket = null;
}

protected virtual void ServerConnectThread()
{
IAsyncResult result;
while (true)
{
if (socket != null && socket.IsBound)
{
try
{
result = socket.BeginAccept(new
AsyncCallback(ServerAcceptConnection), socket);
}
catch (Exception exception)
{
Close();
break;
}
}
else
{
break;
}
// Wait for the EndAccept before issuing a new BeginAccept
result.AsyncWaitHandle.WaitOne();
}
}

Nov 9 '07 #1
4 15956
I don't see anything that is odd about how you are opening and closing
the socket (although what you are doing with the Socket that is returned
from the call to EndAccept isn't shown, I'm sure you call Close on that, but
that shouldn't affect the main socket anyways).

What I am curious about is why you are calling BeginAccept in the first
place. You are waiting on an event in the thread which I am sure you are
setting after you perform the callback where you call EndAccept. Why not
just call Accept in your thread, do your work and be done with it?

Also, are you making calls to Open from multiple threads? If you are,
then I imagine that you could have a race condition where you are creating a
new socket without closing the old one, and since the old socket is still
bound to the port, getting the exception.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"O.B." <fu******@bellsouth.netwrote in message
news:11**********************@d55g2000hsg.googlegr oups.com...
>I have a socket configured as TCP and running as a listener. When I
close socket, it doesn't always free up the port immediately. Even
when no connections have been made to it. So when I open the socket
again, the bind fails because the port is still in use. When I
execute the code in "debug" mode, the problem never occurs. When I
execute the same code in release mode, the problem appears about 20%
of the time.

Here's the code:

protected Socket socket = null;

public void Open()
{
socket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);

socket.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.DontLinger,
true);

IPEndPoint endPoint = new IPEndPoint(
System.Net.IPAddress.Parse(socketConfig.Address),
socketConfig.Port);

socket.Bind(endPoint);
socket.Listen(MAX_NUM_CONNECTIONS);

serverConnectThread = new Thread(ServerConnectThread);
serverConnectThread.Start();
}

public void Close()
{
socket.Close();
socket = null;
}

protected virtual void ServerConnectThread()
{
IAsyncResult result;
while (true)
{
if (socket != null && socket.IsBound)
{
try
{
result = socket.BeginAccept(new
AsyncCallback(ServerAcceptConnection), socket);
}
catch (Exception exception)
{
Close();
break;
}
}
else
{
break;
}
// Wait for the EndAccept before issuing a new BeginAccept
result.AsyncWaitHandle.WaitOne();
}
}
Nov 9 '07 #2
Only one thread is calling the Open operation.

I'm using BeginAccept because it starts a new thread when a connection
is made. The operation specified within BeginAccept goes into a loop
of receiving data from the socket. Granted, I could use "Accept"
instead and create a new thread myself each time. Unless I'm
mistaken, the two approaches do the exact same thing.

In one of my test cases, the socket is opened, closed, and
dereference. The test sleeps 2 seconds and repeats the cycle two more
times. A connection is never made to the socket. In 20% of the
executions, I encounter a socket exception when trying to open the
socket because the port is still in use.


On Nov 9, 11:17 am, "Nicholas Paldino [.NET/C# MVP]"
<m...@spam.guard.caspershouse.comwrote:
I don't see anything that is odd about how you are opening and closing
the socket (although what you are doing with the Socket that is returned
from the call to EndAccept isn't shown, I'm sure you call Close on that, but
that shouldn't affect the main socket anyways).

What I am curious about is why you are calling BeginAccept in the first
place. You are waiting on an event in the thread which I am sure you are
setting after you perform the callback where you call EndAccept. Why not
just call Accept in your thread, do your work and be done with it?

Also, are you making calls to Open from multiple threads? If you are,
then I imagine that you could have a race condition where you are creating a
new socket without closing the old one, and since the old socket is still
bound to the port, getting the exception.

--
- Nicholas Paldino [.NET/C# MVP]
- m...@spam.guard.caspershouse.com

"O.B." <funkj...@bellsouth.netwrote in message

news:11**********************@d55g2000hsg.googlegr oups.com...
I have a socket configured as TCP and running as a listener. When I
close socket, it doesn't always free up the port immediately. Even
when no connections have been made to it. So when I open the socket
again, the bind fails because the port is still in use. When I
execute the code in "debug" mode, the problem never occurs. When I
execute the same code in release mode, the problem appears about 20%
of the time.
Here's the code:
protected Socket socket = null;
public void Open()
{
socket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
socket.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.DontLinger,
true);
IPEndPoint endPoint = new IPEndPoint(
System.Net.IPAddress.Parse(socketConfig.Address),
socketConfig.Port);
socket.Bind(endPoint);
socket.Listen(MAX_NUM_CONNECTIONS);
serverConnectThread = new Thread(ServerConnectThread);
serverConnectThread.Start();
}
public void Close()
{
socket.Close();
socket = null;
}
protected virtual void ServerConnectThread()
{
IAsyncResult result;
while (true)
{
if (socket != null && socket.IsBound)
{
try
{
result = socket.BeginAccept(new
AsyncCallback(ServerAcceptConnection), socket);
}
catch (Exception exception)
{
Close();
break;
}
}
else
{
break;
}
// Wait for the EndAccept before issuing a new BeginAccept
result.AsyncWaitHandle.WaitOne();
}
}

Nov 9 '07 #3
On 2007-11-09 09:17:33 -0800, "Nicholas Paldino [.NET/C# MVP]"
<mv*@spam.guard.caspershouse.comsaid:
I don't see anything that is odd about how you are opening and
closing the socket (although what you are doing with the Socket that is
returned from the call to EndAccept isn't shown, I'm sure you call
Close on that, but that shouldn't affect the main socket anyways).

What I am curious about is why you are calling BeginAccept in the
first place. You are waiting on an event in the thread which I am sure
you are setting after you perform the callback where you call
EndAccept. Why not just call Accept in your thread, do your work and
be done with it?
Agreed. Or alternatively, forget the loop in ServerConnectThread()
(and for that matter, probably forget the "server connect thread"
altogether) and just call BeginAccept() again from within the EndAccept
callback method. This is a more typical use of the async methods.
Also, are you making calls to Open from multiple threads? If you
are, then I imagine that you could have a race condition where you are
creating a new socket without closing the old one, and since the old
socket is still bound to the port, getting the exception.
In addition, be aware that a listening socket simply is not normally
removed right away when closed. See "TIME_WAIT" for more details.
Even in perfectly working code, with or without .NET, it's not uncommon
to have to wait some period of time before you can bind a new socket to
a previously used address.

See SocketOptionName.ReuseAddress for a workaround.

Pete

Nov 9 '07 #4
On 2007-11-09 09:36:06 -0800, "O.B." <fu******@bellsouth.netsaid:
Only one thread is calling the Open operation.

I'm using BeginAccept because it starts a new thread when a connection
is made. The operation specified within BeginAccept goes into a loop
of receiving data from the socket. Granted, I could use "Accept"
instead and create a new thread myself each time. Unless I'm
mistaken, the two approaches do the exact same thing.
Ouch. Don't do that. At the very least, you'll run out of thread pool
threads. It's possible that you'll screw up the async implementation
of the Socket class as well. Make sure that in your callback, you
process the completed operation without delay and return immediately.

If you want to use the async methods, use them correctly. That means
don't create your own threads for the socket. Let the async methods
use the IOCP thread pool as it was designed. In the completion
callback for the various methods (i.e. the methods where you call
EndAccept, EndRecieve, etc.), simply call the "Begin..." method again
to allow a new network operation to occur. After calling EndAccept,
call BeginAccept. After calling EndReceive, call BeginReceive. And so
forth.

If you want to create your own threads for the socket operations, then
don't use the async methods.

Pete

Nov 9 '07 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: simon place | last post by:
Spent some very frustrating hours recoding to find a way of closing a server socket, i'd not thought it would be any problem, however, after complete failure and as a last resort, i looked at the...
8
by: Jim | last post by:
Need some comments from anyone willing to help, please. See the code included below. This compiles with GCC on FreeBSD 4.7. The only point of it is to accept a socket connection. Nothing else...
2
by: L.J.SONG | last post by:
I use following code to create socket and connect to a server app: /// code ///// Socket connecter = null; IPEndPoint localEp = null; IPEndPoint remoteEp = null; IPHostEntry he =...
3
by: Tom Opgenorth | last post by:
I'm experiencing a problem with sockets, and I'm really hoping someone can help me, please and thank you. I've written a TCP Server, which listens on a port for an incoming connection. When the...
5
by: zxo102 | last post by:
Hi, I am doing a small project using socket server and thread in python. This is first time for me to use socket and thread things. Here is my case. I have 20 socket clients. Each client send a...
6
by: alessandro | last post by:
Hi all, This is my framework for create TCP server listening forever on a port and supporting threads: import SocketServer port = 2222 ip = "192.168.0.4"
2
by: kodart | last post by:
Introduction Performance is the main concern to most server application developers. That’s why many of them anticipate using .NET platform to develop high performance server application regardless...
0
by: Riccardo Di Meo | last post by:
Hi everyone, I'm practicing with embedding python into C code and i have encountered a very strange problem: I'm unable to call the "accept" method of a (correctly created) server socket without...
0
by: FragMagnet | last post by:
Hi all, I've run into a bit of a snag while dealing with asynchronous sockets. What I'm trying to do is set a timeout for which the server will listen for a connection from a client, at which...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.