By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
425,925 Members | 732 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 425,925 IT Pros & Developers. It's quick & easy.

Socket remains in CLOSE_WAIT state

P: n/a
I've read many articles on the subject and the majority of them give the same
solution that's in article 821625 on the MSDN website. I'm using the
following code and when a the client disconnects the child socket remains in
the CLOSE_WAIT state. Anyone have any idea what's missing?

----------------------------- Socket Code -----------------------------

namespace Sockets
{
#region Class - SocketClient

public class SocketClient
{
#region Public Delegates

public delegate void MessageReceivedHandler(SocketClient client);
public delegate void ConnectionClosedHandler(SocketClient client);
public delegate void SocketErrorHandler(SocketClient client, Exception e);

#endregion

#region Private Properties and Events

private SocketServer Server;
private NetworkStream Stream;
private TcpClient Client;
private AsyncCallback CallbackReadFunction;
private AsyncCallback CallbackWriteFunction;
private Boolean IsDisposed;

private MessageReceivedHandler OnMessageReceived;
private ConnectionClosedHandler OnConnectionClosed;
private SocketErrorHandler OnSocketError;

#endregion

#region Public Properties

public String IPAddress;
public Int16 Port;
public Object UserData;
public Socket ClientSocket;
public Byte[] RawBuffer;
public Int32 SizeOfRawBuffer;
public Int32 MessageLength;
public StringBuilder StringBuffer;

#endregion

#region Public User Defined Properties

public Boolean IsAvailable;

#endregion

#region Constructor

public SocketClient(Int32 SizeOfRawBuffer, Object UserData,
MessageReceivedHandler MessageHandler, ConnectionClosedHandler CloseHandler,
SocketErrorHandler ErrorHandler)
{
this.SizeOfRawBuffer = SizeOfRawBuffer;
RawBuffer = new Byte[SizeOfRawBuffer];
MessageLength = 0;

this.UserData = UserData;

StringBuffer = new StringBuilder();

OnMessageReceived = MessageHandler;
OnConnectionClosed = CloseHandler;
OnSocketError = ErrorHandler;

CallbackReadFunction = new AsyncCallback(ReceiveComplete);
CallbackWriteFunction = new AsyncCallback(SendComplete);

IsAvailable = true;
IsDisposed = false;
}

public SocketClient(SocketServer ServerSocket, Socket ClientSocket, String
IPAddress, Int16 Port, Int32 SizeOfRawBuffer, Object UserData,
MessageReceivedHandler MessageHandler, ConnectionClosedHandler CloseHandler,
SocketErrorHandler ErrorHandler)
{
Server = ServerSocket;
ClientSocket = ClientSocket;

this.IPAddress = IPAddress;
this.Port = Port;

OnMessageReceived = MessageHandler;
OnConnectionClosed = CloseHandler;
OnSocketError = ErrorHandler;

this.SizeOfRawBuffer = SizeOfRawBuffer;
RawBuffer = new Byte[SizeOfRawBuffer];

this.UserData = UserData;

StringBuffer = new StringBuilder();
Stream = new NetworkStream(ClientSocket);

CallbackReadFunction = new AsyncCallback(ReceiveComplete);
CallbackWriteFunction = new AsyncCallback(SendComplete);

IsAvailable = true;
IsDisposed = false;

ClientSocket.SetSocketOption(System.Net.Sockets.So cketOptionLevel.Socket,
System.Net.Sockets.SocketOptionName.ReceiveBuffer, 1048576);
ClientSocket.SetSocketOption(System.Net.Sockets.So cketOptionLevel.Socket,
System.Net.Sockets.SocketOptionName.SendBuffer, 1048576);
ClientSocket.SetSocketOption(System.Net.Sockets.So cketOptionLevel.Socket,
System.Net.Sockets.SocketOptionName.KeepAlive, 1);
ClientSocket.SetSocketOption(System.Net.Sockets.So cketOptionLevel.Socket,
System.Net.Sockets.SocketOptionName.DontLinger, 0);
ClientSocket.SetSocketOption(System.Net.Sockets.So cketOptionLevel.Tcp,
System.Net.Sockets.SocketOptionName.NoDelay, 1);
}

~SocketClient()
{
if (!IsDisposed)
Dispose();
}

public void Dispose()
{
try
{
IsDisposed = true;
Disconnect();
}

catch
{
}

if (Server != null)
Server.RemoveSocket(this);
}

#endregion

#region Private Methods

private void ReceiveComplete(IAsyncResult ar)
{
try
{
if (Stream.CanRead)
{
MessageLength = Stream.EndRead(ar);

if (MessageLength > 0)
{
try
{
OnMessageReceived(this);
}
catch
{
}

Receive();
}
else
throw new Exception("Shut Down");
}
}
catch
{
try
{
OnConnectionClosed(this);
}
catch
{
}

Dispose();
}
}

private void SendComplete(IAsyncResult ar)
{
try
{
if (Stream.CanWrite)
Stream.EndWrite(ar);
}
catch (Exception)
{
}
}

#endregion

#region Public Methods

public void Connect(String IPAddress, Int16 Port)
{
try
{
if (Stream == null)
{
this.IPAddress = IPAddress;
this.Port = Port;

Client = new TcpClient(IPAddress, Port);
Stream = Client.GetStream();

Client.ReceiveBufferSize = 1048576;
Client.SendBufferSize = 1048576;
Client.NoDelay = true;
Client.LingerState = new System.Net.Sockets.LingerOption(false, 0);

ClientSocket = null;

Receive();
}
}
catch (System.Net.Sockets.SocketException e)
{
throw new Exception(e.Message, e.InnerException);
}
}

public void Disconnect()
{
if (Stream != null)
Stream.Close();

if (Client != null)
Client.Close();

if (ClientSocket != null)
ClientSocket.Close();

ClientSocket = null;
Client = null;
Stream = null;
}

public void Send(String Message)
{
if ((Stream != null) && (Stream.CanWrite))
{
Byte[] RawBuffer = System.Text.Encoding.ASCII.GetBytes(Message);
Stream.BeginWrite(RawBuffer, 0, RawBuffer.GetLength(0),
CallbackWriteFunction, null);
}
else
throw new Exception("Socket Closed");
}

public void Send(Byte[] RawBuffer)
{
if ((Stream != null) && (Stream.CanWrite))
Stream.BeginWrite(RawBuffer, 0, RawBuffer.GetLength(0),
CallbackWriteFunction, null);
else
throw new Exception("Socket Closed");
}

public void Send(Char Character)
{
if ((Stream != null) && (Stream.CanWrite))
{
Byte[] RawBuffer = { Convert.ToByte(Character) };
Stream.BeginWrite(RawBuffer, 0, RawBuffer.GetLength(0),
CallbackWriteFunction, null);
}
else
throw new Exception("Socket Closed");
}

public void Receive()
{
if ((Stream != null) && (Stream.CanRead))
Stream.BeginRead(RawBuffer, 0, SizeOfRawBuffer, CallbackReadFunction,
null);
else
throw new Exception("Socket Closed");
}

#endregion
}

#endregion

#region Class - SocketServer

public class SocketServer
{
#region Public Delagates

public delegate void MessageReceivedHandler(SocketClient client);
public delegate void ConnectionClosedHandler(SocketClient client);
public delegate void SocketErrorHandler(SocketClient client, Exception e);
public delegate void ConnectionAcceptedHandler(SocketClient client);

#endregion

#region Private Properties and Events

private TcpListener Listener;
private Int32 SizeOfRawBuffer;
private Thread AcceptThread;
private Boolean IsDisposed;
private Object SocketListCS;

private MessageReceivedHandler OnMessageReceived;
private ConnectionClosedHandler OnConnectionClosed;
private SocketErrorHandler OnSocketError;
private ConnectionAcceptedHandler OnConnectionAccepted;

#endregion

#region Public Properties

public ArrayList SocketClientList;
public String IPAddress;
public Int16 Port;
public Object UserData;

#endregion

#region Constructor

public SocketServer()
{
SocketListCS = new Object();
IsDisposed = false;
}

~SocketServer()
{
if (!IsDisposed)
Stop();
}

public void Dispose()
{
try
{
IsDisposed = true;

if (AcceptThread != null)
Stop();
}
catch
{
}
}

#endregion

#region Private Methods

private SocketClient AddSocket(SocketClient Client)
{
Monitor.Enter(SocketListCS);

try
{
SocketClientList.Add(Client);
}
catch (Exception e)
{
Monitor.Exit(SocketListCS);

throw e;
}

Monitor.Exit(SocketListCS);

return Client;
}

public void RemoveSocket(SocketClient client)
{
Monitor.Enter(SocketListCS);

try
{
SocketClientList.Remove(client);
}
catch
{
}

Monitor.Exit(SocketListCS);
}

private void Accept_Thread()
{
Socket socket = null;
SocketClient client = null;

try
{
Listener = new TcpListener(Dns.Resolve(IPAddress).AddressList[0], Port);
Listener.Start();

for (;;)
{
try
{
socket = Listener.AcceptSocket();
}
catch (System.Net.Sockets.SocketException e)
{
if (e.ErrorCode != 10004)
{
OnSocketError(null, e);
OnSocketError(null, new Exception("Waiting for new connection 1"));

if (socket != null)
if (socket.Connected)
socket.Close();
}
else
{
OnSocketError(null, new Exception("Shutting Down Accept Thread"));
break;
}
}
catch (Exception e)
{
OnSocketError(null, e);
OnSocketError(null, new Exception("Waiting for new connection 2"));

if (socket != null)
if (socket.Connected)
socket.Close();
}

try
{
if (socket.Connected)
{
client = AddSocket(new SocketClient(this,
socket,
socket.RemoteEndPoint.ToString().Substring(0,15),
Port,
SizeOfRawBuffer,
UserData,
new SocketClient.MessageReceivedHandler(OnMessageRecei ved),
new SocketClient.ConnectionClosedHandler(OnConnectionC losed),
new SocketClient.SocketErrorHandler(OnSocketError)));

OnConnectionAccepted(client);

client.Receive();
}
}
catch (Exception e)
{
OnSocketError(null, e);
OnSocketError(null, new Exception("Waiting for new connection 3"));
}
}
}
catch (Exception e)
{
OnSocketError(null, e);
OnSocketError(null, new Exception("Shutting Down Accept Thread"));

if (socket != null)
if (socket.Connected)
socket.Close();
}
}

#endregion

#region Public Methods

public void Start(String IPAddress, Int16 Port, Int32 SizeOfRawBuffer,
Object UserData, MessageReceivedHandler MessageHandler,
ConnectionAcceptedHandler AcceptHandler, ConnectionClosedHandler
CloseHandler, SocketErrorHandler ErrorHandler)
{
if (AcceptThread == null)
{
this.IPAddress = IPAddress;
this.Port = Port;

SocketClientList = new ArrayList();

OnMessageReceived = MessageHandler;
OnConnectionAccepted = AcceptHandler;
OnConnectionClosed = CloseHandler;
OnSocketError = ErrorHandler;

this.SizeOfRawBuffer = SizeOfRawBuffer;
this.UserData = UserData;

ThreadStart ThreadDelegate = new ThreadStart(Accept_Thread);
AcceptThread = new Thread(ThreadDelegate);
AcceptThread.Name = "Accept";
AcceptThread.Start();
}
}

public void Stop()
{
if (AcceptThread != null)
{
Listener.Stop();
AcceptThread.Join();
AcceptThread = null;
}

for (int i = 0; i < SocketClientList.Count; ++i)
((SocketClient) SocketClientList[i]).Dispose();

GC.Collect();
GC.WaitForPendingFinalizers();

SocketClientList.Clear();

OnMessageReceived = null;
OnConnectionAccepted = null;
OnConnectionClosed = null;
OnSocketError = null;

SizeOfRawBuffer = 0;
UserData = null;
}

#endregion
}

#endregion
}

Nov 1 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
Bob
CLOSE_WAIT is normal, it does not mean the socket is open. It means the
socket is closed but is waiting for any extra data that may be sent to it.
This is used so that a new socket is not created on the same port immeditly
and receive packets from an old connection. There is a default time of (I
think) 120 seconds in this state, which can be changed in the registry.

"DreJoh" <Dr****@discussions.microsoft.com> wrote in message
news:92**********************************@microsof t.com...
I've read many articles on the subject and the majority of them give the
same
solution that's in article 821625 on the MSDN website. I'm using the
following code and when a the client disconnects the child socket remains
in
the CLOSE_WAIT state. Anyone have any idea what's missing?

----------------------------- Socket Code -----------------------------

namespace Sockets
{
#region Class - SocketClient

public class SocketClient
{
#region Public Delegates

public delegate void MessageReceivedHandler(SocketClient client);
public delegate void ConnectionClosedHandler(SocketClient client);
public delegate void SocketErrorHandler(SocketClient client, Exception e);

#endregion

#region Private Properties and Events

private SocketServer Server;
private NetworkStream Stream;
private TcpClient Client;
private AsyncCallback CallbackReadFunction;
private AsyncCallback CallbackWriteFunction;
private Boolean IsDisposed;

private MessageReceivedHandler OnMessageReceived;
private ConnectionClosedHandler OnConnectionClosed;
private SocketErrorHandler OnSocketError;

#endregion

#region Public Properties

public String IPAddress;
public Int16 Port;
public Object UserData;
public Socket ClientSocket;
public Byte[] RawBuffer;
public Int32 SizeOfRawBuffer;
public Int32 MessageLength;
public StringBuilder StringBuffer;

#endregion

#region Public User Defined Properties

public Boolean IsAvailable;

#endregion

#region Constructor

public SocketClient(Int32 SizeOfRawBuffer, Object UserData,
MessageReceivedHandler MessageHandler, ConnectionClosedHandler
CloseHandler,
SocketErrorHandler ErrorHandler)
{
this.SizeOfRawBuffer = SizeOfRawBuffer;
RawBuffer = new Byte[SizeOfRawBuffer];
MessageLength = 0;

this.UserData = UserData;

StringBuffer = new StringBuilder();

OnMessageReceived = MessageHandler;
OnConnectionClosed = CloseHandler;
OnSocketError = ErrorHandler;

CallbackReadFunction = new AsyncCallback(ReceiveComplete);
CallbackWriteFunction = new AsyncCallback(SendComplete);

IsAvailable = true;
IsDisposed = false;
}

public SocketClient(SocketServer ServerSocket, Socket ClientSocket, String
IPAddress, Int16 Port, Int32 SizeOfRawBuffer, Object UserData,
MessageReceivedHandler MessageHandler, ConnectionClosedHandler
CloseHandler,
SocketErrorHandler ErrorHandler)
{
Server = ServerSocket;
ClientSocket = ClientSocket;

this.IPAddress = IPAddress;
this.Port = Port;

OnMessageReceived = MessageHandler;
OnConnectionClosed = CloseHandler;
OnSocketError = ErrorHandler;

this.SizeOfRawBuffer = SizeOfRawBuffer;
RawBuffer = new Byte[SizeOfRawBuffer];

this.UserData = UserData;

StringBuffer = new StringBuilder();
Stream = new NetworkStream(ClientSocket);

CallbackReadFunction = new AsyncCallback(ReceiveComplete);
CallbackWriteFunction = new AsyncCallback(SendComplete);

IsAvailable = true;
IsDisposed = false;

ClientSocket.SetSocketOption(System.Net.Sockets.So cketOptionLevel.Socket,
System.Net.Sockets.SocketOptionName.ReceiveBuffer, 1048576);
ClientSocket.SetSocketOption(System.Net.Sockets.So cketOptionLevel.Socket,
System.Net.Sockets.SocketOptionName.SendBuffer, 1048576);
ClientSocket.SetSocketOption(System.Net.Sockets.So cketOptionLevel.Socket,
System.Net.Sockets.SocketOptionName.KeepAlive, 1);
ClientSocket.SetSocketOption(System.Net.Sockets.So cketOptionLevel.Socket,
System.Net.Sockets.SocketOptionName.DontLinger, 0);
ClientSocket.SetSocketOption(System.Net.Sockets.So cketOptionLevel.Tcp,
System.Net.Sockets.SocketOptionName.NoDelay, 1);
}

~SocketClient()
{
if (!IsDisposed)
Dispose();
}

public void Dispose()
{
try
{
IsDisposed = true;
Disconnect();
}

catch
{
}

if (Server != null)
Server.RemoveSocket(this);
}

#endregion

#region Private Methods

private void ReceiveComplete(IAsyncResult ar)
{
try
{
if (Stream.CanRead)
{
MessageLength = Stream.EndRead(ar);

if (MessageLength > 0)
{
try
{
OnMessageReceived(this);
}
catch
{
}

Receive();
}
else
throw new Exception("Shut Down");
}
}
catch
{
try
{
OnConnectionClosed(this);
}
catch
{
}

Dispose();
}
}

private void SendComplete(IAsyncResult ar)
{
try
{
if (Stream.CanWrite)
Stream.EndWrite(ar);
}
catch (Exception)
{
}
}

#endregion

#region Public Methods

public void Connect(String IPAddress, Int16 Port)
{
try
{
if (Stream == null)
{
this.IPAddress = IPAddress;
this.Port = Port;

Client = new TcpClient(IPAddress, Port);
Stream = Client.GetStream();

Client.ReceiveBufferSize = 1048576;
Client.SendBufferSize = 1048576;
Client.NoDelay = true;
Client.LingerState = new System.Net.Sockets.LingerOption(false, 0);

ClientSocket = null;

Receive();
}
}
catch (System.Net.Sockets.SocketException e)
{
throw new Exception(e.Message, e.InnerException);
}
}

public void Disconnect()
{
if (Stream != null)
Stream.Close();

if (Client != null)
Client.Close();

if (ClientSocket != null)
ClientSocket.Close();

ClientSocket = null;
Client = null;
Stream = null;
}

public void Send(String Message)
{
if ((Stream != null) && (Stream.CanWrite))
{
Byte[] RawBuffer = System.Text.Encoding.ASCII.GetBytes(Message);
Stream.BeginWrite(RawBuffer, 0, RawBuffer.GetLength(0),
CallbackWriteFunction, null);
}
else
throw new Exception("Socket Closed");
}

public void Send(Byte[] RawBuffer)
{
if ((Stream != null) && (Stream.CanWrite))
Stream.BeginWrite(RawBuffer, 0, RawBuffer.GetLength(0),
CallbackWriteFunction, null);
else
throw new Exception("Socket Closed");
}

public void Send(Char Character)
{
if ((Stream != null) && (Stream.CanWrite))
{
Byte[] RawBuffer = { Convert.ToByte(Character) };
Stream.BeginWrite(RawBuffer, 0, RawBuffer.GetLength(0),
CallbackWriteFunction, null);
}
else
throw new Exception("Socket Closed");
}

public void Receive()
{
if ((Stream != null) && (Stream.CanRead))
Stream.BeginRead(RawBuffer, 0, SizeOfRawBuffer, CallbackReadFunction,
null);
else
throw new Exception("Socket Closed");
}

#endregion
}

#endregion

#region Class - SocketServer

public class SocketServer
{
#region Public Delagates

public delegate void MessageReceivedHandler(SocketClient client);
public delegate void ConnectionClosedHandler(SocketClient client);
public delegate void SocketErrorHandler(SocketClient client, Exception e);
public delegate void ConnectionAcceptedHandler(SocketClient client);

#endregion

#region Private Properties and Events

private TcpListener Listener;
private Int32 SizeOfRawBuffer;
private Thread AcceptThread;
private Boolean IsDisposed;
private Object SocketListCS;

private MessageReceivedHandler OnMessageReceived;
private ConnectionClosedHandler OnConnectionClosed;
private SocketErrorHandler OnSocketError;
private ConnectionAcceptedHandler OnConnectionAccepted;

#endregion

#region Public Properties

public ArrayList SocketClientList;
public String IPAddress;
public Int16 Port;
public Object UserData;

#endregion

#region Constructor

public SocketServer()
{
SocketListCS = new Object();
IsDisposed = false;
}

~SocketServer()
{
if (!IsDisposed)
Stop();
}

public void Dispose()
{
try
{
IsDisposed = true;

if (AcceptThread != null)
Stop();
}
catch
{
}
}

#endregion

#region Private Methods

private SocketClient AddSocket(SocketClient Client)
{
Monitor.Enter(SocketListCS);

try
{
SocketClientList.Add(Client);
}
catch (Exception e)
{
Monitor.Exit(SocketListCS);

throw e;
}

Monitor.Exit(SocketListCS);

return Client;
}

public void RemoveSocket(SocketClient client)
{
Monitor.Enter(SocketListCS);

try
{
SocketClientList.Remove(client);
}
catch
{
}

Monitor.Exit(SocketListCS);
}

private void Accept_Thread()
{
Socket socket = null;
SocketClient client = null;

try
{
Listener = new TcpListener(Dns.Resolve(IPAddress).AddressList[0], Port);
Listener.Start();

for (;;)
{
try
{
socket = Listener.AcceptSocket();
}
catch (System.Net.Sockets.SocketException e)
{
if (e.ErrorCode != 10004)
{
OnSocketError(null, e);
OnSocketError(null, new Exception("Waiting for new connection 1"));

if (socket != null)
if (socket.Connected)
socket.Close();
}
else
{
OnSocketError(null, new Exception("Shutting Down Accept Thread"));
break;
}
}
catch (Exception e)
{
OnSocketError(null, e);
OnSocketError(null, new Exception("Waiting for new connection 2"));

if (socket != null)
if (socket.Connected)
socket.Close();
}

try
{
if (socket.Connected)
{
client = AddSocket(new SocketClient(this,
socket,
socket.RemoteEndPoint.ToString().Substring(0,15),
Port,
SizeOfRawBuffer,
UserData,
new SocketClient.MessageReceivedHandler(OnMessageRecei ved),
new SocketClient.ConnectionClosedHandler(OnConnectionC losed),
new SocketClient.SocketErrorHandler(OnSocketError)));

OnConnectionAccepted(client);

client.Receive();
}
}
catch (Exception e)
{
OnSocketError(null, e);
OnSocketError(null, new Exception("Waiting for new connection 3"));
}
}
}
catch (Exception e)
{
OnSocketError(null, e);
OnSocketError(null, new Exception("Shutting Down Accept Thread"));

if (socket != null)
if (socket.Connected)
socket.Close();
}
}

#endregion

#region Public Methods

public void Start(String IPAddress, Int16 Port, Int32 SizeOfRawBuffer,
Object UserData, MessageReceivedHandler MessageHandler,
ConnectionAcceptedHandler AcceptHandler, ConnectionClosedHandler
CloseHandler, SocketErrorHandler ErrorHandler)
{
if (AcceptThread == null)
{
this.IPAddress = IPAddress;
this.Port = Port;

SocketClientList = new ArrayList();

OnMessageReceived = MessageHandler;
OnConnectionAccepted = AcceptHandler;
OnConnectionClosed = CloseHandler;
OnSocketError = ErrorHandler;

this.SizeOfRawBuffer = SizeOfRawBuffer;
this.UserData = UserData;

ThreadStart ThreadDelegate = new ThreadStart(Accept_Thread);
AcceptThread = new Thread(ThreadDelegate);
AcceptThread.Name = "Accept";
AcceptThread.Start();
}
}

public void Stop()
{
if (AcceptThread != null)
{
Listener.Stop();
AcceptThread.Join();
AcceptThread = null;
}

for (int i = 0; i < SocketClientList.Count; ++i)
((SocketClient) SocketClientList[i]).Dispose();

GC.Collect();
GC.WaitForPendingFinalizers();

SocketClientList.Clear();

OnMessageReceived = null;
OnConnectionAccepted = null;
OnConnectionClosed = null;
OnSocketError = null;

SizeOfRawBuffer = 0;
UserData = null;
}

#endregion
}

#endregion
}

Nov 2 '05 #2

P: n/a
The problem is that the CLOSE_WAIT states never go away and they build up
over time (hours). I have to shutdown the socket server after a few hours to
clear them off.

I reduced the time to KeepAlive, but it didn't help. Are there any other
registry parameters I might need to set?

"Bob" wrote:
CLOSE_WAIT is normal, it does not mean the socket is open. It means the
socket is closed but is waiting for any extra data that may be sent to it.
This is used so that a new socket is not created on the same port immeditly
and receive packets from an old connection. There is a default time of (I
think) 120 seconds in this state, which can be changed in the registry.

"DreJoh" <Dr****@discussions.microsoft.com> wrote in message
news:92**********************************@microsof t.com...
I've read many articles on the subject and the majority of them give the
same
solution that's in article 821625 on the MSDN website. I'm using the
following code and when a the client disconnects the child socket remains
in
the CLOSE_WAIT state. Anyone have any idea what's missing?

----------------------------- Socket Code -----------------------------

namespace Sockets
{
#region Class - SocketClient

public class SocketClient
{
#region Public Delegates

public delegate void MessageReceivedHandler(SocketClient client);
public delegate void ConnectionClosedHandler(SocketClient client);
public delegate void SocketErrorHandler(SocketClient client, Exception e);

#endregion

#region Private Properties and Events

private SocketServer Server;
private NetworkStream Stream;
private TcpClient Client;
private AsyncCallback CallbackReadFunction;
private AsyncCallback CallbackWriteFunction;
private Boolean IsDisposed;

private MessageReceivedHandler OnMessageReceived;
private ConnectionClosedHandler OnConnectionClosed;
private SocketErrorHandler OnSocketError;

#endregion

#region Public Properties

public String IPAddress;
public Int16 Port;
public Object UserData;
public Socket ClientSocket;
public Byte[] RawBuffer;
public Int32 SizeOfRawBuffer;
public Int32 MessageLength;
public StringBuilder StringBuffer;

#endregion

#region Public User Defined Properties

public Boolean IsAvailable;

#endregion

#region Constructor

public SocketClient(Int32 SizeOfRawBuffer, Object UserData,
MessageReceivedHandler MessageHandler, ConnectionClosedHandler
CloseHandler,
SocketErrorHandler ErrorHandler)
{
this.SizeOfRawBuffer = SizeOfRawBuffer;
RawBuffer = new Byte[SizeOfRawBuffer];
MessageLength = 0;

this.UserData = UserData;

StringBuffer = new StringBuilder();

OnMessageReceived = MessageHandler;
OnConnectionClosed = CloseHandler;
OnSocketError = ErrorHandler;

CallbackReadFunction = new AsyncCallback(ReceiveComplete);
CallbackWriteFunction = new AsyncCallback(SendComplete);

IsAvailable = true;
IsDisposed = false;
}

public SocketClient(SocketServer ServerSocket, Socket ClientSocket, String
IPAddress, Int16 Port, Int32 SizeOfRawBuffer, Object UserData,
MessageReceivedHandler MessageHandler, ConnectionClosedHandler
CloseHandler,
SocketErrorHandler ErrorHandler)
{
Server = ServerSocket;
ClientSocket = ClientSocket;

this.IPAddress = IPAddress;
this.Port = Port;

OnMessageReceived = MessageHandler;
OnConnectionClosed = CloseHandler;
OnSocketError = ErrorHandler;

this.SizeOfRawBuffer = SizeOfRawBuffer;
RawBuffer = new Byte[SizeOfRawBuffer];

this.UserData = UserData;

StringBuffer = new StringBuilder();
Stream = new NetworkStream(ClientSocket);

CallbackReadFunction = new AsyncCallback(ReceiveComplete);
CallbackWriteFunction = new AsyncCallback(SendComplete);

IsAvailable = true;
IsDisposed = false;

ClientSocket.SetSocketOption(System.Net.Sockets.So cketOptionLevel.Socket,
System.Net.Sockets.SocketOptionName.ReceiveBuffer, 1048576);
ClientSocket.SetSocketOption(System.Net.Sockets.So cketOptionLevel.Socket,
System.Net.Sockets.SocketOptionName.SendBuffer, 1048576);
ClientSocket.SetSocketOption(System.Net.Sockets.So cketOptionLevel.Socket,
System.Net.Sockets.SocketOptionName.KeepAlive, 1);
ClientSocket.SetSocketOption(System.Net.Sockets.So cketOptionLevel.Socket,
System.Net.Sockets.SocketOptionName.DontLinger, 0);
ClientSocket.SetSocketOption(System.Net.Sockets.So cketOptionLevel.Tcp,
System.Net.Sockets.SocketOptionName.NoDelay, 1);
}

~SocketClient()
{
if (!IsDisposed)
Dispose();
}

public void Dispose()
{
try
{
IsDisposed = true;
Disconnect();
}

catch
{
}

if (Server != null)
Server.RemoveSocket(this);
}

#endregion

#region Private Methods

private void ReceiveComplete(IAsyncResult ar)
{
try
{
if (Stream.CanRead)
{
MessageLength = Stream.EndRead(ar);

if (MessageLength > 0)
{
try
{
OnMessageReceived(this);
}
catch
{
}

Receive();
}
else
throw new Exception("Shut Down");
}
}
catch
{
try
{
OnConnectionClosed(this);
}
catch
{
}

Dispose();
}
}

private void SendComplete(IAsyncResult ar)
{
try
{
if (Stream.CanWrite)
Stream.EndWrite(ar);
}
catch (Exception)
{
}
}

#endregion

#region Public Methods

public void Connect(String IPAddress, Int16 Port)
{
try
{
if (Stream == null)
{
this.IPAddress = IPAddress;
this.Port = Port;

Client = new TcpClient(IPAddress, Port);
Stream = Client.GetStream();

Client.ReceiveBufferSize = 1048576;
Client.SendBufferSize = 1048576;
Client.NoDelay = true;
Client.LingerState = new System.Net.Sockets.LingerOption(false, 0);

ClientSocket = null;

Receive();
}
}
catch (System.Net.Sockets.SocketException e)
{
throw new Exception(e.Message, e.InnerException);
}
}

public void Disconnect()
{
if (Stream != null)
Stream.Close();

if (Client != null)
Client.Close();

if (ClientSocket != null)
ClientSocket.Close();

ClientSocket = null;
Client = null;
Stream = null;
}

public void Send(String Message)
{
if ((Stream != null) && (Stream.CanWrite))
{
Byte[] RawBuffer = System.Text.Encoding.ASCII.GetBytes(Message);
Stream.BeginWrite(RawBuffer, 0, RawBuffer.GetLength(0),
CallbackWriteFunction, null);
}
else
throw new Exception("Socket Closed");
}

public void Send(Byte[] RawBuffer)
{
if ((Stream != null) && (Stream.CanWrite))
Stream.BeginWrite(RawBuffer, 0, RawBuffer.GetLength(0),
CallbackWriteFunction, null);
else
throw new Exception("Socket Closed");
}

public void Send(Char Character)
{
if ((Stream != null) && (Stream.CanWrite))
{
Byte[] RawBuffer = { Convert.ToByte(Character) };
Stream.BeginWrite(RawBuffer, 0, RawBuffer.GetLength(0),
CallbackWriteFunction, null);
}
else
throw new Exception("Socket Closed");
}

public void Receive()
{
if ((Stream != null) && (Stream.CanRead))
Stream.BeginRead(RawBuffer, 0, SizeOfRawBuffer, CallbackReadFunction,
null);
else
throw new Exception("Socket Closed");
}

Nov 2 '05 #3

P: n/a
Bob
Normally if the socket is not closed correctly it stays in the FIN_WAIT_X
state not TIME_WAIT. But if you are using all the ports up because you are
creating a lot of connections very fast then you can increase the number of
allowed user ports in the registry. By default this is 5000 (Minus 1024
reserved ports.) This can be increased to 65535. Search MSDN for
MaxUserPort and it will give more information on increasing this value.
"DreJoh" <Dr****@discussions.microsoft.com> wrote in message
news:67**********************************@microsof t.com...
The problem is that the CLOSE_WAIT states never go away and they build up
over time (hours). I have to shutdown the socket server after a few hours
to
clear them off.

I reduced the time to KeepAlive, but it didn't help. Are there any other
registry parameters I might need to set?

"Bob" wrote:
CLOSE_WAIT is normal, it does not mean the socket is open. It means the
socket is closed but is waiting for any extra data that may be sent to
it.
This is used so that a new socket is not created on the same port
immeditly
and receive packets from an old connection. There is a default time of (I
think) 120 seconds in this state, which can be changed in the registry.

"DreJoh" <Dr****@discussions.microsoft.com> wrote in message
news:92**********************************@microsof t.com...
> I've read many articles on the subject and the majority of them give
> the
> same
> solution that's in article 821625 on the MSDN website. I'm using the
> following code and when a the client disconnects the child socket
> remains
> in
> the CLOSE_WAIT state. Anyone have any idea what's missing?
>
> ----------------------------- Socket Code -----------------------------
>
> namespace Sockets
> {
> #region Class - SocketClient
>
> public class SocketClient
> {
> #region Public Delegates
>
> public delegate void MessageReceivedHandler(SocketClient client);
> public delegate void ConnectionClosedHandler(SocketClient client);
> public delegate void SocketErrorHandler(SocketClient client, Exception
> e);
>
> #endregion
>
> #region Private Properties and Events
>
> private SocketServer Server;
> private NetworkStream Stream;
> private TcpClient Client;
> private AsyncCallback CallbackReadFunction;
> private AsyncCallback CallbackWriteFunction;
> private Boolean IsDisposed;
>
> private MessageReceivedHandler OnMessageReceived;
> private ConnectionClosedHandler OnConnectionClosed;
> private SocketErrorHandler OnSocketError;
>
> #endregion
>
> #region Public Properties
>
> public String IPAddress;
> public Int16 Port;
> public Object UserData;
> public Socket ClientSocket;
> public Byte[] RawBuffer;
> public Int32 SizeOfRawBuffer;
> public Int32 MessageLength;
> public StringBuilder StringBuffer;
>
> #endregion
>
> #region Public User Defined Properties
>
> public Boolean IsAvailable;
>
> #endregion
>
> #region Constructor
>
> public SocketClient(Int32 SizeOfRawBuffer, Object UserData,
> MessageReceivedHandler MessageHandler, ConnectionClosedHandler
> CloseHandler,
> SocketErrorHandler ErrorHandler)
> {
> this.SizeOfRawBuffer = SizeOfRawBuffer;
> RawBuffer = new Byte[SizeOfRawBuffer];
> MessageLength = 0;
>
> this.UserData = UserData;
>
> StringBuffer = new StringBuilder();
>
> OnMessageReceived = MessageHandler;
> OnConnectionClosed = CloseHandler;
> OnSocketError = ErrorHandler;
>
> CallbackReadFunction = new AsyncCallback(ReceiveComplete);
> CallbackWriteFunction = new AsyncCallback(SendComplete);
>
> IsAvailable = true;
> IsDisposed = false;
> }
>
> public SocketClient(SocketServer ServerSocket, Socket ClientSocket,
> String
> IPAddress, Int16 Port, Int32 SizeOfRawBuffer, Object UserData,
> MessageReceivedHandler MessageHandler, ConnectionClosedHandler
> CloseHandler,
> SocketErrorHandler ErrorHandler)
> {
> Server = ServerSocket;
> ClientSocket = ClientSocket;
>
> this.IPAddress = IPAddress;
> this.Port = Port;
>
> OnMessageReceived = MessageHandler;
> OnConnectionClosed = CloseHandler;
> OnSocketError = ErrorHandler;
>
> this.SizeOfRawBuffer = SizeOfRawBuffer;
> RawBuffer = new Byte[SizeOfRawBuffer];
>
> this.UserData = UserData;
>
> StringBuffer = new StringBuilder();
> Stream = new NetworkStream(ClientSocket);
>
> CallbackReadFunction = new AsyncCallback(ReceiveComplete);
> CallbackWriteFunction = new AsyncCallback(SendComplete);
>
> IsAvailable = true;
> IsDisposed = false;
>
> ClientSocket.SetSocketOption(System.Net.Sockets.So cketOptionLevel.Socket,
> System.Net.Sockets.SocketOptionName.ReceiveBuffer, 1048576);
> ClientSocket.SetSocketOption(System.Net.Sockets.So cketOptionLevel.Socket,
> System.Net.Sockets.SocketOptionName.SendBuffer, 1048576);
> ClientSocket.SetSocketOption(System.Net.Sockets.So cketOptionLevel.Socket,
> System.Net.Sockets.SocketOptionName.KeepAlive, 1);
> ClientSocket.SetSocketOption(System.Net.Sockets.So cketOptionLevel.Socket,
> System.Net.Sockets.SocketOptionName.DontLinger, 0);
> ClientSocket.SetSocketOption(System.Net.Sockets.So cketOptionLevel.Tcp,
> System.Net.Sockets.SocketOptionName.NoDelay, 1);
> }
>
> ~SocketClient()
> {
> if (!IsDisposed)
> Dispose();
> }
>
> public void Dispose()
> {
> try
> {
> IsDisposed = true;
> Disconnect();
> }
>
> catch
> {
> }
>
> if (Server != null)
> Server.RemoveSocket(this);
> }
>
> #endregion
>
> #region Private Methods
>
> private void ReceiveComplete(IAsyncResult ar)
> {
> try
> {
> if (Stream.CanRead)
> {
> MessageLength = Stream.EndRead(ar);
>
> if (MessageLength > 0)
> {
> try
> {
> OnMessageReceived(this);
> }
> catch
> {
> }
>
> Receive();
> }
> else
> throw new Exception("Shut Down");
> }
> }
> catch
> {
> try
> {
> OnConnectionClosed(this);
> }
> catch
> {
> }
>
> Dispose();
> }
> }
>
> private void SendComplete(IAsyncResult ar)
> {
> try
> {
> if (Stream.CanWrite)
> Stream.EndWrite(ar);
> }
> catch (Exception)
> {
> }
> }
>
> #endregion
>
> #region Public Methods
>
> public void Connect(String IPAddress, Int16 Port)
> {
> try
> {
> if (Stream == null)
> {
> this.IPAddress = IPAddress;
> this.Port = Port;
>
> Client = new TcpClient(IPAddress, Port);
> Stream = Client.GetStream();
>
> Client.ReceiveBufferSize = 1048576;
> Client.SendBufferSize = 1048576;
> Client.NoDelay = true;
> Client.LingerState = new System.Net.Sockets.LingerOption(false,
> 0);
>
> ClientSocket = null;
>
> Receive();
> }
> }
> catch (System.Net.Sockets.SocketException e)
> {
> throw new Exception(e.Message, e.InnerException);
> }
> }
>
> public void Disconnect()
> {
> if (Stream != null)
> Stream.Close();
>
> if (Client != null)
> Client.Close();
>
> if (ClientSocket != null)
> ClientSocket.Close();
>
> ClientSocket = null;
> Client = null;
> Stream = null;
> }
>
> public void Send(String Message)
> {
> if ((Stream != null) && (Stream.CanWrite))
> {
> Byte[] RawBuffer = System.Text.Encoding.ASCII.GetBytes(Message);
> Stream.BeginWrite(RawBuffer, 0, RawBuffer.GetLength(0),
> CallbackWriteFunction, null);
> }
> else
> throw new Exception("Socket Closed");
> }
>
> public void Send(Byte[] RawBuffer)
> {
> if ((Stream != null) && (Stream.CanWrite))
> Stream.BeginWrite(RawBuffer, 0, RawBuffer.GetLength(0),
> CallbackWriteFunction, null);
> else
> throw new Exception("Socket Closed");
> }
>
> public void Send(Char Character)
> {
> if ((Stream != null) && (Stream.CanWrite))
> {
> Byte[] RawBuffer = { Convert.ToByte(Character) };
> Stream.BeginWrite(RawBuffer, 0, RawBuffer.GetLength(0),
> CallbackWriteFunction, null);
> }
> else
> throw new Exception("Socket Closed");
> }
>
> public void Receive()
> {
> if ((Stream != null) && (Stream.CanRead))
> Stream.BeginRead(RawBuffer, 0, SizeOfRawBuffer, CallbackReadFunction,
> null);
> else
> throw new Exception("Socket Closed");
> }

Nov 2 '05 #4

P: n/a
I have attempted to tune with several registry settings including
MaxUserPort. I set it to 32768. But, I'm not having a problem with
connections coming in too fast. In, fact as I am writing I have one
CLOSE_WAIT state on the machine that has been there for over 6 hours. I will
go away only when I shutdown the socket. This is not a production evironment.
I'm testing and trying to solve this problem on a test machine.

I don't have a sniffer, so I wrote a batch file that loops with no delay and
redirects output to a file. The command in the loop is netstat -na -p tcp
output. I did this in a attempt to see the various states. I can only catch
CLOSE_WAIT and FIN_WAIT_2. That's with the batch file and/or done manually.

Hey, after six hours my CLOSE_WAIT has gone away. I guess I can live with
that until I figure something else out.

Thanks Bob

"Bob" wrote:
Normally if the socket is not closed correctly it stays in the FIN_WAIT_X
state not TIME_WAIT. But if you are using all the ports up because you are
creating a lot of connections very fast then you can increase the number of
allowed user ports in the registry. By default this is 5000 (Minus 1024
reserved ports.) This can be increased to 65535. Search MSDN for
MaxUserPort and it will give more information on increasing this value.
"DreJoh" <Dr****@discussions.microsoft.com> wrote in message
news:67**********************************@microsof t.com...
The problem is that the CLOSE_WAIT states never go away and they build up
over time (hours). I have to shutdown the socket server after a few hours
to
clear them off.

I reduced the time to KeepAlive, but it didn't help. Are there any other
registry parameters I might need to set?

"Bob" wrote:
CLOSE_WAIT is normal, it does not mean the socket is open. It means the
socket is closed but is waiting for any extra data that may be sent to
it.
This is used so that a new socket is not created on the same port
immeditly
and receive packets from an old connection. There is a default time of (I
think) 120 seconds in this state, which can be changed in the registry.

"DreJoh" <Dr****@discussions.microsoft.com> wrote in message
news:92**********************************@microsof t.com...
> I've read many articles on the subject and the majority of them give
> the
> same
> solution that's in article 821625 on the MSDN website. I'm using the
> following code and when a the client disconnects the child socket
> remains
> in
> the CLOSE_WAIT state. Anyone have any idea what's missing?
>
> ----------------------------- Socket Code -----------------------------
>
> namespace Sockets
> {
> #region Class - SocketClient
>
> public class SocketClient
> {
> #region Public Delegates
>
> public delegate void MessageReceivedHandler(SocketClient client);
> public delegate void ConnectionClosedHandler(SocketClient client);
> public delegate void SocketErrorHandler(SocketClient client, Exception
> e);
>
> #endregion
>
> #region Private Properties and Events
>
> private SocketServer Server;
> private NetworkStream Stream;
> private TcpClient Client;
> private AsyncCallback CallbackReadFunction;
> private AsyncCallback CallbackWriteFunction;
> private Boolean IsDisposed;
>
> private MessageReceivedHandler OnMessageReceived;
> private ConnectionClosedHandler OnConnectionClosed;
> private SocketErrorHandler OnSocketError;
>
> #endregion
>
> #region Public Properties
>
> public String IPAddress;
> public Int16 Port;
> public Object UserData;
> public Socket ClientSocket;
> public Byte[] RawBuffer;
> public Int32 SizeOfRawBuffer;
> public Int32 MessageLength;
> public StringBuilder StringBuffer;
>
> #endregion
>
> #region Public User Defined Properties
>
> public Boolean IsAvailable;
>
> #endregion
>
> #region Constructor
>
> public SocketClient(Int32 SizeOfRawBuffer, Object UserData,
> MessageReceivedHandler MessageHandler, ConnectionClosedHandler
> CloseHandler,
> SocketErrorHandler ErrorHandler)
> {
> this.SizeOfRawBuffer = SizeOfRawBuffer;
> RawBuffer = new Byte[SizeOfRawBuffer];
> MessageLength = 0;
>
> this.UserData = UserData;
>
> StringBuffer = new StringBuilder();
>
> OnMessageReceived = MessageHandler;
> OnConnectionClosed = CloseHandler;
> OnSocketError = ErrorHandler;
>
> CallbackReadFunction = new AsyncCallback(ReceiveComplete);
> CallbackWriteFunction = new AsyncCallback(SendComplete);
>
> IsAvailable = true;
> IsDisposed = false;
> }
>
> public SocketClient(SocketServer ServerSocket, Socket ClientSocket,
> String
> IPAddress, Int16 Port, Int32 SizeOfRawBuffer, Object UserData,
> MessageReceivedHandler MessageHandler, ConnectionClosedHandler
> CloseHandler,
> SocketErrorHandler ErrorHandler)
> {
> Server = ServerSocket;
> ClientSocket = ClientSocket;
>
> this.IPAddress = IPAddress;
> this.Port = Port;
>
> OnMessageReceived = MessageHandler;
> OnConnectionClosed = CloseHandler;
> OnSocketError = ErrorHandler;
>
> this.SizeOfRawBuffer = SizeOfRawBuffer;
> RawBuffer = new Byte[SizeOfRawBuffer];
>
> this.UserData = UserData;
>
> StringBuffer = new StringBuilder();
> Stream = new NetworkStream(ClientSocket);
>
> CallbackReadFunction = new AsyncCallback(ReceiveComplete);
> CallbackWriteFunction = new AsyncCallback(SendComplete);
>
> IsAvailable = true;
> IsDisposed = false;
>
> ClientSocket.SetSocketOption(System.Net.Sockets.So cketOptionLevel.Socket,
> System.Net.Sockets.SocketOptionName.ReceiveBuffer, 1048576);
> ClientSocket.SetSocketOption(System.Net.Sockets.So cketOptionLevel.Socket,
> System.Net.Sockets.SocketOptionName.SendBuffer, 1048576);
> ClientSocket.SetSocketOption(System.Net.Sockets.So cketOptionLevel.Socket,
> System.Net.Sockets.SocketOptionName.KeepAlive, 1);
> ClientSocket.SetSocketOption(System.Net.Sockets.So cketOptionLevel.Socket,
> System.Net.Sockets.SocketOptionName.DontLinger, 0);
> ClientSocket.SetSocketOption(System.Net.Sockets.So cketOptionLevel.Tcp,
> System.Net.Sockets.SocketOptionName.NoDelay, 1);
> }
>
> ~SocketClient()
> {
> if (!IsDisposed)
> Dispose();
> }
>
> public void Dispose()
> {
> try
> {
> IsDisposed = true;
> Disconnect();
> }
>
> catch
> {
> }
>
> if (Server != null)
> Server.RemoveSocket(this);
> }
>
> #endregion
>
> #region Private Methods
>
> private void ReceiveComplete(IAsyncResult ar)
> {
> try
> {
> if (Stream.CanRead)
> {
> MessageLength = Stream.EndRead(ar);
>
> if (MessageLength > 0)
> {
> try
> {
> OnMessageReceived(this);
> }
> catch
> {
> }
>
> Receive();
> }
> else
> throw new Exception("Shut Down");
> }
> }
> catch
> {
> try
> {
> OnConnectionClosed(this);
> }
> catch
> {
> }
>
> Dispose();
> }
> }
>
> private void SendComplete(IAsyncResult ar)
> {
> try
> {
> if (Stream.CanWrite)
> Stream.EndWrite(ar);
> }
> catch (Exception)
> {
> }
> }
>
> #endregion
>
> #region Public Methods
>
> public void Connect(String IPAddress, Int16 Port)
> {
> try
> {
> if (Stream == null)
> {
> this.IPAddress = IPAddress;
> this.Port = Port;
>
> Client = new TcpClient(IPAddress, Port);
> Stream = Client.GetStream();
>
> Client.ReceiveBufferSize = 1048576;
> Client.SendBufferSize = 1048576;
> Client.NoDelay = true;
> Client.LingerState = new System.Net.Sockets.LingerOption(false,
> 0);
>
> ClientSocket = null;
>
> Receive();
> }
> }
> catch (System.Net.Sockets.SocketException e)
> {
> throw new Exception(e.Message, e.InnerException);
> }
> }
>
> public void Disconnect()
> {
> if (Stream != null)
> Stream.Close();
>
> if (Client != null)
> Client.Close();
>
> if (ClientSocket != null)
> ClientSocket.Close();
>
> ClientSocket = null;
> Client = null;
> Stream = null;
> }
>
> public void Send(String Message)
> {
> if ((Stream != null) && (Stream.CanWrite))
> {
> Byte[] RawBuffer = System.Text.Encoding.ASCII.GetBytes(Message);
> Stream.BeginWrite(RawBuffer, 0, RawBuffer.GetLength(0),
> CallbackWriteFunction, null);
> }
> else
> throw new Exception("Socket Closed");
> }
>
> public void Send(Byte[] RawBuffer)
> {

Nov 2 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.