R
Rob Gravereaux
Visual Studio 2005, .Net 2.0, Vista, XP.
I have a client Tcp socket that is bound to a particular port and connecting
to a remote host. In order to allow reconnects I'm setting the ReuseAddress
socket option. This is somewhat dubious I know, but...
With the ReuseAddress option, a bind to a local port in a TIME_WAIT state
(netstat -a) does succeed, but the socket connect is failing with the 'Only
one usage of each socket address...' message. For example, in the following
code, call Connect(), then Disconnect(), then Connect() again (within the
TIME_WAIT period, about 4 minutes) and s.Connect(...) throws an exception.
There are a few posts I've seen that specify using the ReuseAddress socket
option in this scenario. Am I missing something? How can I successfully bind
to a local port that is already in a TIME_WAIT state and successfully
connect?
Some sample code...
private bool m_bConnected;
private Socket m_Socket;
private void Connect()
{
string sLocalHost = txtInboundLocalHost.Text;
int iLocalPort = int.Parse(txtInboundLocalPort.Text);
string sRemoteHost = txtInboundRemoteHost.Text;
int iRemotePort = int.Parse(txtInboundRemotePort.Text);
// Create socket and set options.
Socket s = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
s.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.ReuseAddress, (int)1);
// Create local endpoint if desired.
if(!string.IsNullOrEmpty(sLocalHost))
{
// Use specified interface and port on local machine.
IPAddress ip;
if (IPAddress.TryParse(sLocalHost, out ip)
&& (ip.AddressFamily ==
System.Net.Sockets.AddressFamily.InterNetwork))
{
s.Bind(new IPEndPoint(ip, iLocalPort));
}
else
throw new ApplicationException("Not a valid IP
Address.");
}
else if(iLocalPort > 0)
{
// Use specified port on local machine, all interfaces.
s.Bind(new IPEndPoint(IPAddress.Any, iLocalPort));
}
// Otherwise, use default host & port...
// Connect to remote. This errors if port is in TIME_WAIT state.
s.Connect(sRemoteHost, iRemotePort);
m_Socket = s;
m_bConnected = true;
}
private void Disconnect()
{
if (m_bConnected)
{
// Shutdown socket and allow reuse.
m_Socket.Shutdown(SocketShutdown.Both);
m_Socket.Disconnect(true);
}
m_bConnected = false;
}
TIA.
Rob Gravereaux
I have a client Tcp socket that is bound to a particular port and connecting
to a remote host. In order to allow reconnects I'm setting the ReuseAddress
socket option. This is somewhat dubious I know, but...
With the ReuseAddress option, a bind to a local port in a TIME_WAIT state
(netstat -a) does succeed, but the socket connect is failing with the 'Only
one usage of each socket address...' message. For example, in the following
code, call Connect(), then Disconnect(), then Connect() again (within the
TIME_WAIT period, about 4 minutes) and s.Connect(...) throws an exception.
There are a few posts I've seen that specify using the ReuseAddress socket
option in this scenario. Am I missing something? How can I successfully bind
to a local port that is already in a TIME_WAIT state and successfully
connect?
Some sample code...
private bool m_bConnected;
private Socket m_Socket;
private void Connect()
{
string sLocalHost = txtInboundLocalHost.Text;
int iLocalPort = int.Parse(txtInboundLocalPort.Text);
string sRemoteHost = txtInboundRemoteHost.Text;
int iRemotePort = int.Parse(txtInboundRemotePort.Text);
// Create socket and set options.
Socket s = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
s.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.ReuseAddress, (int)1);
// Create local endpoint if desired.
if(!string.IsNullOrEmpty(sLocalHost))
{
// Use specified interface and port on local machine.
IPAddress ip;
if (IPAddress.TryParse(sLocalHost, out ip)
&& (ip.AddressFamily ==
System.Net.Sockets.AddressFamily.InterNetwork))
{
s.Bind(new IPEndPoint(ip, iLocalPort));
}
else
throw new ApplicationException("Not a valid IP
Address.");
}
else if(iLocalPort > 0)
{
// Use specified port on local machine, all interfaces.
s.Bind(new IPEndPoint(IPAddress.Any, iLocalPort));
}
// Otherwise, use default host & port...
// Connect to remote. This errors if port is in TIME_WAIT state.
s.Connect(sRemoteHost, iRemotePort);
m_Socket = s;
m_bConnected = true;
}
private void Disconnect()
{
if (m_bConnected)
{
// Shutdown socket and allow reuse.
m_Socket.Shutdown(SocketShutdown.Both);
m_Socket.Disconnect(true);
}
m_bConnected = false;
}
TIA.
Rob Gravereaux