This is my first question and I hope you can help me.
I have 2 programs, a Server and a Client and my problem is in the Client.
After 2 or 3 days of running, it uses more than 300MB of RAM (I can tell this by seeing the TaskManager) and never releases it! Also, I have to say that this Client receives data every second from GPS devices.
I have analyzed my Client with the ANTS Memory Profiler and I noticed that I create an object several times and they are never destroyed.
Here is my code:
private static TcpClient _client;
private readonly ManualResetEvent _receiveDone = new ManualResetEvent(false);
public void Receive()
{
if (_client.Connected)
{
_receiveDone.Reset();
ObjectState state = new ObjectState();
state.WorkSocket = _client.Client;
state.Data = new byte[_client.ReceiveBufferSize];
_client.Client.BeginReceive(state.Data, 0, Convert.ToInt32(_client.ReceiveBufferSize), 0, ReceiveCallback, state);
if (!_receiveDone.WaitOne(20000))
{
//after 20 seconds WITHOUT RECEIVING DATA, do some code to test if the connection is alive
}
}
}
void ReceiveCallback(IAsyncResult ar)
{
ObjectState state = (ObjectState)ar.AsyncState;
Socket client = state.WorkSocket;
if (client.Connected)
{
int bytesRead = client.EndReceive(ar);
if (bytesRead > 0)
{
string response = Encoding.ASCII.GetString(state.Data, 0, bytesRead);
doProcess(response);
client.BeginReceive(state.Data, 0, Convert.ToInt32(_client.ReceiveBufferSize), 0, ReceiveCallback, state);
_receiveDone.Set();
}
else
{
//Disconnection
}
}
}
public class ObjectState
{
public Socket WorkSocket;
public byte[] Data;
}
The ANTS Memory Profiler tells me I have thousands of live instances of byte[]. (because I always create new instances of ObjectState)
First thing I wanted to do: Dispose all the ObjectState that I create after I call BeginReceive, but I only get the first message.
Then I wanted to stop using the ObjectState... How?
This is my modified code:
private _data byte[];
public void Receive()
{
if (_client.Connected)
{
_receiveDone.Reset();
_data = new byte[_client.ReceiveBufferSize];
_client.Client.BeginReceive(_data, 0, Convert.ToInt32(_client.ReceiveBufferSize), 0, ReceiveCallback, null);
if (!_receiveDone.WaitOne(20000))
{
//after 20 seconds of inactivity do some code to test if the connectio is alive
}
}
}
void ReceiveCallback(IAsyncResult ar)
{
Socket client = _cliente.Client;
if (client.Connected)
{
int bytesRead = client.EndReceive(ar);
if (bytesRead > 0)
{
string response = Encoding.ASCII.GetString(_data, 0, bytesRead);
doProcess(response);
client.BeginReceive(_data, 0, Convert.ToInt32(_client.ReceiveBufferSize), 0, ReceiveCallback, null);
_receiveDone.Set();
}
else
{
//Disconnection
}
}
}
What's wrong with this? I only get the first message, so this is not good.
Then if I remove the _receiveDone.Set it gets all the messages, BUT the _receiveDone.WaitOne(2000) always is executed every 20 seconds, no matter if I actually am receiving data, and this is not good either.
So my question is, what can I do to reduce the using of so much RAM? I hope this explains well what my problem is.
EDIT:
I uploaded these images, I hope they can be helpful too.
if (client.Connected)
{
int bytesRead = client.EndReceive(ar);
// etc..
Calling EndReceive is not optional, you have to call it or you'll leak resources. Use try/catch to catch an ObjectDisposedException.
I think the primary problem is that you're depending on BeginReceive to return 0 bytes when there's nothing available. But that's not how it works. BeginReceive will block until there is data available, or until the client disconnects.
In the first case, the ReceiveCallback passes the state object to client.BeginReceive. Now you have an ObjectState instance out there waiting for data from the client. The _receiveDone event is set, so your Receive method exits but the client connection is still open and you have a pending asynchronous read.
The next time Receive is called, it will create another ObjectState instance and issue another asynchronous read request.
The second case is pretty scary. Your _data array is at class scope and gets reallocated every time. So it's possible that an asynchronous read can fill the buffer you pass it, but then the data is lost when you get to ReceiveCallback.
Your code only does the timeout check for the first receive. After that, things can hang indefinitely. I would suggest something more like:
private _data byte[];
private bool _receiving = false;
public void StartReceiving()
{
if (_receiving)
{
// ERROR: Already receiving
throw new InvalidOperationException();
}
_receiving = true;
Receive();
}
public void Receive()
{
if (_client.Connected)
{
_data = new byte[_client.ReceiveBufferSize];
var ir _client.Client.BeginReceive(_data, 0, Convert.ToInt32(_client.ReceiveBufferSize), 0, ReceiveCallback, null);
if (!_ir.WaitOne(20000))
{
//after 20 seconds of inactivity do some code to test if the connectio is alive
}
}
}
void ReceiveCallback(IAsyncResult ar)
{
Socket client = _cliente.Client;
int bytesRead;
try
{
bytesRead = client.EndReceive(ar);
if (bytesRead > 0)
{
string response = Encoding.ASCII.GetString(_data, 0, bytesRead);
doProcess(response);
// Calling Receive here ensures that the timeout check happens
// with every read.
Receive();
}
else
{
_receiving = false;
}
}
catch
{
// Catch SocketException and others here
}
}
Note that you don't need the _receiveDone event. You can check it with the IAsyncResult.WaitHandle.
Related
I use multi threaded async socket for receiving data from XDomainRequest. I didn't have a problem about receiving data till now but I don't like my current way of doing that. So I wonder if there is a better idea.
Here is my StateObject:
public class StateObject
{
public Socket workSocket = null;
public const int BufferSize = 256;
public byte[] buffer = new byte[BufferSize];
public StringBuilder sb = new StringBuilder();
// stores total byte length which comes from XDomainRequest
public int totalReceivedBuffer = 0;
// stores byte lenght comes when each call of ReceiveCallBack
public int receivedBuffer = 0;
}
In AcceptCallBack I create StateObject:
StateObject state = new StateObject();
state.workSocket = handler;
Then I have to do a weird thing to learn total received bytes:
System.Threading.Thread.Sleep(200);
state.totalReceivedBuffer = handler.Available;
If I don't put sleep, I get available value less than the actual value. In ReceiveCallBack method, I get received byte lenght for small part of data:
int numBytesReceived = handler.EndReceive(result);
I get StateObject which comes from AcceptCallBack and add that received bytes to it:
state = (StateObject)result.AsyncState;
handler = state.workSocket;
state.receivedBuffer += numBytesReceived;
then I control if it got equal to total bytes:
if(state.receivedBuffer == state.totalReceivedBuffer)
{
// do the job
}
else
{
// Call ReceiveCallBack again
}
Is there a better way of doing that?
EDIT:
I'm calling ReceiveCallBack at the end of AcceptCallBack like that:
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
My ReceiveCallBack function is here. I cut some of it:
public static void ReceiveCallback(IAsyncResult result)
{
StateObject state = null;
Socket handler = null;
try
{
state = (StateObject)result.AsyncState;
handler = state.workSocket;
string clientIP = ((IPEndPoint)handler.RemoteEndPoint).Address.ToString();
// See how many bytes received
int numBytesReceived = handler.EndReceive(result);
if (!handler.Connected)
{
handler.Close();
return;
}
if (numBytesReceived > 0)
{
state.receivedBuffer += numBytesReceived;
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, numBytesReceived));
// Read all data line by line
string[] lines = state.sb.ToString().Split('\n');
if (state.receivedBuffer == state.totalReceivedBuffer)
{
// All data came
// do the job according to lines array
}
else
{
// continue receiving
handler.BeginReceive(state.buffer, 0, state.buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), state);
}
}
}
catch (ObjectDisposedException ex)
{
// Don't care
}
catch (SocketException ex)
{
#region SocketException
if (ex.ErrorCode == 10054)
{
// HATA: "An existing connection was forcibly closed by the remote host"
Globals.ErrorLogYaz(_log, Globals.GetCurrentMethod(), "Karşı taraf işlem tamamlanmadan bağlantıyı kapattı!", ex.StackTrace);
handler.Close();
}
#endregion
}
catch (Exception ex)
{
Globals.ErrorLogYaz(_log, Globals.GetCurrentMethod(), ex.Message, ex.StackTrace);
handler.Close();
}
}
The way to read data from a connection is to actually call Receive and examine how many bytes you got. There is no way to predict how many will come. Available is the amount of data available right now. How could the receiver possibly know how much more the sender will send in the future? It can't know.
Call Receive in a loop until it returns 0 (the connection is closed) or until you know by some other means that all bytes are received.
Since you seem to be a beginner with sockets and there does not seem to be a reason to use async you probably should use synchronous IO. It is much simpler.
I am trying to write a server that will listen on a port, accept an incoming client connection and then put that client connection in a stack to wait for a future message to arrive. Ideally when a message arrives, I'd like to fire an event that then allows the server to perform an action.
I've written almost all of that...I am using AcceptTCPClient() to actually pick up a new client connection which is fine. I then create a thread, pass the socket to a class that holds the client state and some other data. However the only way I can think to block and wait for a future incoming connection on that thread is to call something like NetworkStream.Read() which then blocks until bytes arrive.
So here is the fundamental problem - I am using Protobuff-net which allows me to deserialise a network stream rather than an individual byte array. So by reading the first couple of bytes, I've got to reset the read, pass the networkstream to the protobuff deserialize method and then continue.
All I really want is a method that blocks until some bytes are detected but doesn't require me to actually read the bytes until I'm ready.
Anyone have any ideas how I could achieve this?
Update
As the comments below suggested, this is not something that seems to be supported by .Net therefore the simplest solution seems to be to use Tsukasa example below which uses async read/write.
I've written it to consume all the bytes on the wire and then pass those bytes to the protobuff Deserialize method.
Not what I wanted but it works fine. Thanks all for the assitance.
private byte[] buffer = new byte[256];
private Socket socket;
private NetworkStream networkStream;
private AsyncCallback callbackRead;
private AsyncCallback callbackWrite;
public Socket Socket
{
get { return socket; }
}
public ClientProxy(Socket clientSocket)
{
socket = clientSocket;
networkStream = new NetworkStream(clientSocket);
callbackRead = new AsyncCallback(OnReadComplete);
callbackWrite = new AsyncCallback(OnWriteComplete);
}
public void ReadAsync()
{
networkStream.BeginRead(buffer, 0, buffer.Length, callbackRead, null);
}
private void OnReadComplete(IAsyncResult ar)
{
int bytesRead = networkStream.EndRead(ar);
if (bytesRead > 0)
{
MemoryStream stream = new MemoryStream(buffer);
Message data;
data = Serializer.DeserializeWithLengthPrefix<Message>(stream, PrefixStyle.Fixed32);
if (data.Type == Chat.Type.User && data.Action == Chat.Action.Add)
{
Communication.RegisterClient(data.From, socket.Handle.ToString());
}
Communication.readMessage(data);
ReadAsync();
}
else
{
networkStream.Close();
socket.Close();
networkStream = null;
socket = null;
}
}
You can poll the DataAvailable property but it's unreliable and inefficient.
A better way is to prefix the protobuf stream with a length prefix. It also allows to do a read without reading the protobuf message. By using a prefix you can invoke a asynchronous read which will return as soon as there is something available (just configure the Read to read only 4 bytes if you are using a length header).
If you don't want to take care of the network operations yourself you can use my apache licensed library. Here is a sample using protobuf-net: http://blog.gauffin.org/2014/06/easy-and-perfomant-clientserver-communication-with-protobuf-net-griffin-framework/
BeginRead() which would allow you to have an event called when data is ready, that way your process can be in a blocked state where the OS will only awake it when the resource is ready
class Client
{
private byte[] buffer = new byte[256];
private Socket socket;
private NetworkStream networkStream;
private AsyncCallback callbackRead;
private AsyncCallback callbackWrite;
public Client(Socket clientSocket)
{
socket = clientSocket;
networkStream = new NetworkStream(clientSocket);
callbackRead = new AsyncCallback(OnReadComplete);
callbackWrite = new AsyncCallback(OnWriteComplete);
}
public void StartRead()
{
networkStream.BeginRead(buffer, 0, buffer.Length, callbackRead, null);
}
private void OnReadComplete(IAsyncResult ar)
{
int bytesRead = networkStream.EndRead(ar);
if (bytesRead > 0)
{
string s = System.Text.Encoding.ASCII.GetString(buffer, 0, bytesRead);
//do something with complete data here
networkStream.BeginWrite(buffer, 0, bytesRead, callbackWrite, null);
}
else
{
networkStream.Close();
socket.Close();
networkStream = null;
socket = null;
}
}
private void OnWriteComplete(IAsyncResult ar)
{
networkStream.EndWrite(ar);
networkStream.BeginRead(buffer, 0, buffer.Length, callbackRead, null);
}
}
Usage
bool running = true;
IPAddress localAddr = IPAddress.Parse("127.0.0.1");
TcpListener tcpListener = new TcpListener(localAddr, 3000);
tcpListener.Start();
while (running)
{
while (!tcpListener.Pending())
{
Thread.Sleep(10);
}
Socket socket = tcpListener.AcceptSocket();
Client client = new Client(socket);
client.StartRead();
}
Hi stack overflow members.
I'm struggling with some simple code but I can't get it done.
I have this asynchronous server which waits for connections.
while (clientSocket.Connected)
{
try
{
clientSocket.BeginReceive(so.buffer, 0, 200, SocketFlags.None
, new AsyncCallback(wait),so);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
where so(shorted StateObject) it's my class:
internal class StateObject
{
public TcpClient client;
public byte[] buffer;
public StateObject()
{
buffer = new byte[200];
client = new TcpClient();
}
}
I use this class to put out the information on the callback function. However I get the system lacked sufficient buffer space or because a queue was full.
I posted a short piece from the actual program.
One interesting issue, is that if I write:
while (clientSocket.Connected)
{
try
{
byte[] buffer = new byte[200];
clientSocket.BeginReceive(buffer, 0, 200, SocketFlags.None
, new AsyncCallback(wait),so);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
it will work, but I will not be able to pull out the buffer from the asynchronous function(wait).
I'm struggling with this and I can't find answers.
The while loop shouldn't be there, just call beginreceive after the endreceive.
This is a poor example, but may give you some ideas:
public class AsyncTCP
{
public void StartReceive()
{
byte[] buffer = new byte[200];
clientSocket.BeginReceive(buffer, 0, 200, SocketFlags.None, (state) =>
{
int bytesReceived = clientSocket.EndReceive(state);
// handle buffer.
if(bytesReceived != 0)
StartReceive();
} ,so);
}
}
If it's about getting the state within the EndReceive handler:
private void StartReceive()
{
StateObject myState = new StateObject();
myState.buffer = new byte[200];
myState.client = _client; // or whatever
myState.client.BeginReceive(so.buffer, 0, 200, SocketFlags.None, new AsyncCallback(wait),myState);
}
private void EndReceive(IAsyncResult result)
{
StateObject myState = (StateObject)result.State;
int bytesReceived = myState.client.EndReceive(result);
// handle myState.buffer
StartReceive();
}
I think there are better ways to do this, like:
- only constructing a receive buffer ones.
- put some packet header/data with lengths in it.
Good luck
How about using some TPL functions. So your code can be simplified a lot
int readBytes = await s.ReceiveTaskAsync(buffer, 0, buffer.Length);
This is the extension method ReceiveTaskAsync
public static class SocketExtensions
{
public static Task<int> ReceiveTaskAsync(this Socket socket, byte[] buffer, int offset, int count)
{
return Task.Factory.FromAsync<int>(
socket.BeginReceive(buffer, offset, count, SocketFlags.None, null, socket),
socket.EndReceive);
}
}
The problem is here
while (clientSocket.Connected)//checks connected
{
try
{
clientSocket.BeginReceive(so.buffer, 0, 200, SocketFlags.None, new AsyncCallback(wait),so);//says begin receive and continues to do endlessly
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
You've to call BeginReceive again only after you received the data.
Here's and example from msdn how to do that.
I resolved my previous problem(I just needed to remove the while loop, however I messed it up with some code from a synchronous server).
Now I have another problem, so I will use this same thread.
From what I've searched, and understood, you can open an asynchronous server with BecinAccept like this(main method):
IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, 8082);
TcpListener tcpListener = new TcpListener(IPAddress.Any, 8082);
server = tcpListener.Server;
server.Bind(ipEndPoint);
server.Listen(4);
server.BeginAccept(new AsyncCallback(beginConnection), server);
Then:
static void beginConnection(IAsyncResult iar)
{
Console.WriteLine("Client connected");
Socket s = (Socket)iar.AsyncState;
server = s.EndAccept(iar);
server.Listen(4); // this line was initially absent
server.BeginAccept(beginConnection, s);
}
I want to be able to connect to this server multiple clients.
However, when I try to do this, only the first client connects itself.
The client it's a simple socket, which just echoes back from the server, what we read from the console.
I thought that since in the main method I've called server.Listen(4), I will be able to connect 4 clients.
Then I thought of calling recursively BeginAccept in the beginConnection method.
And last, I received the error, that I must call first the Listen method, so I added that too.
Still no luck.
I've a thread that runs following tcpConnect method. I wish to stop it at any given time by setting Program.PrepareExit to true. However my program is stuck at:
Int32 bytes = stream.Read(data, 0, data.Length); and doesn't really react to Program.PrepareExit set to true. How can i make it to always quit when I tell it so?
public static readonly Thread MyThreadTcpClient = new Thread(ThreadTcpClient);
private static void ThreadTcpClient() {
Connections.tcpConnect(ClientTcpIp, ClientTcpPort);
}
public static void Main() {
MyThreadTcpClient.Start();
.... some code....
Program.PrepareExit = true;
}
public static bool tcpConnect(string varClientIp, int varClientPort) {
var client = new TcpClient();
try {
client = new TcpClient(varClientIp, varClientPort) {NoDelay = true};
NetworkStream stream = client.GetStream();
var data = new Byte[256];
while (!Program.PrepareExit) {
Int32 bytes = stream.Read(data, 0, data.Length);
string varReadData = Encoding.ASCII.GetString(data, 0, bytes);
if (varReadData != "" && varReadData != "echo") {
VerificationQueue.EnqueueRelease(varReadData);
}
}
} catch (ArgumentNullException e) {
MessageBox.Show(e.ToString(), "ArgumentNullException");
tcpConnect(varClientIp, varClientPort);
} catch (SocketException e) {
MessageBox.Show(e.ToString(), "SocketException");
tcpConnect(varClientIp, varClientPort);
} catch (IOException e) {
if (e.ToString() != "Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.") {
}
MessageBox.Show(e.ToString());
tcpConnect(varClientIp, varClientPort);
} finally {
client.Close();
}
return false;
}
Three options suggest themselves:
Make the thread a daemon (background) thread. The process will exit when the only live threads are daemon threads
Set a timeout on the read call, possibly having to change to use the underlying socket API. That won't be pretty, to be honest.
Use asynchronous IO. Also a bit of a pain.
Do you need this thread to do anything in terms of an orderly shutdown? If not, the daemon thread approach would probably be simplest.
I'm working on a web server in C# and I have it running on Asynchronous socket calls. The weird thing is that for some reason, when you start loading pages, the 3rd request is where the browser won't connect. It just keeps saying "Connecting..." and doesn't ever stop. If I hit stop. and then refresh, it will load again, but if I try another time after that it does the thing where it doesn't load again. And it continues in that cycle. I'm not really sure what is making it do that.
The code is kind of hacked together from a couple of examples and some old code I had. Any miscellaneous tips would be helpful as well.
Heres my little Listener class that handles everything
(pastied here. thought it might be easier to read this way)
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using irek.Request;
using irek.Configuration;
namespace irek.Server
{
public class Listener
{
private int port;
private Socket server;
private Byte[] data = new Byte[2048];
static ManualResetEvent allDone = new ManualResetEvent(false);
public Config config;
public Listener(Config cfg)
{
port = int.Parse(cfg.Get("port"));
config = cfg;
ServicePointManager.DefaultConnectionLimit = 20;
}
public void Run()
{
server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint iep = new IPEndPoint(IPAddress.Any, port);
server.Bind(iep);
Console.WriteLine("Server Initialized.");
server.Listen(5);
Console.WriteLine("Listening...");
while (true)
{
allDone.Reset();
server.BeginAccept(new AsyncCallback(AcceptCon), server);
allDone.WaitOne();
}
}
private void AcceptCon(IAsyncResult iar)
{
allDone.Set();
Socket s = (Socket)iar.AsyncState;
Socket s2 = s.EndAccept(iar);
SocketStateObject state = new SocketStateObject();
state.workSocket = s2;
s2.BeginReceive(state.buffer, 0, SocketStateObject.BUFFER_SIZE, 0, new AsyncCallback(Read), state);
}
private void Read(IAsyncResult iar)
{
try
{
SocketStateObject state = (SocketStateObject)iar.AsyncState;
Socket s = state.workSocket;
int read = s.EndReceive(iar);
if (read > 0)
{
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, read));
SocketStateObject nextState = new SocketStateObject();
nextState.workSocket = s;
s.BeginReceive(state.buffer, 0, SocketStateObject.BUFFER_SIZE, 0, new AsyncCallback(Read), nextState);
}
if (state.sb.Length > 1)
{
string requestString = state.sb.ToString();
// HANDLE REQUEST HERE
byte[] answer = RequestHandler.Handle(requestString, ref config);
// Temporary response
/*
string resp = "<h1>It Works!</h1>";
string head = "HTTP/1.1 200 OK\r\nContent-Type: text/html;\r\nServer: irek\r\nContent-Length:"+resp.Length+"\r\n\r\n";
byte[] answer = Encoding.ASCII.GetBytes(head+resp);
// end temp.
*/
state.workSocket.BeginSend(answer, 0, answer.Length, SocketFlags.None, new AsyncCallback(Send), s);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
return;
}
}
private void Send(IAsyncResult iar)
{
try
{
SocketStateObject state = (SocketStateObject)iar.AsyncState;
int sent = state.workSocket.EndSend(iar);
state.workSocket.Shutdown(SocketShutdown.Both);
state.workSocket.Close();
}
catch (Exception)
{
}
return;
}
}
}
And my SocketStateObject:
public class SocketStateObject
{
public Socket workSocket = null;
public const int BUFFER_SIZE = 1024;
public byte[] buffer = new byte[BUFFER_SIZE];
public StringBuilder sb = new StringBuilder();
}
** EDIT **
I have updated the code with some suggestions from Chris Taylor.
Just looking at the code quickly, I suspect that you might stop enquing your AsyncReads because s.Available is returning 0, I am refering to the following code
if (read > 0)
{
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, read));
if (s.Available > 0)
{
s.BeginReceive(state.buffer, 0, SocketStateObject.BUFFER_SIZE, 0, new AsyncCallback(Read), state);
return;
}
}
To confirm, change the above to the following
if (read > 0)
{
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, read));
SocketStateObject nextState = new SocketStateObject();
nextState.workSocket = s;
s.BeginReceive(state.buffer, 0, SocketStateObject.BUFFER_SIZE, 0, new AsyncCallback(Read), nextState);
}
This is not the complete correction of the code, but it will confirm if this is the problem. You need to make sure that you are closing your sockets correctly etc.
Update
I also noticed that you are sending the socket in as the state in the call to BeginSend.
state.workSocket.BeginSend(answer, 0, answer.Length, SocketFlags.None, new AsyncCallback(Send), state.workSocket);
However, your callback Send is casting the AsyncState to SocketStateObject
SocketStateObject state = (SocketStateObject)iar.AsyncState;
This will be raising InvalidCastExceptions which you are just hiding by adding the empty catch. I am sure others will agree, this is exceptionally bad practice having empty catches it hides so much info that you could be using to debug your problem.
Completely random guess:
http://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.defaultconnectionlimit.aspx
The maximum number of concurrent
connections allowed by a ServicePoint
object. The default value is 2.
You should also note that there is a race condition in your code. In Run(), you wait for allDone before calling BeginAccept again:
while (true)
{
allDone.Reset();
server.BeginAccept(new AsyncCallback(AcceptCon), server);
allDone.WaitOne(); // <------
}
This is fine, however in your AcceptConn callback, the event is set at the top of the method:
private void AcceptCon(IAsyncResult iar)
{
allDone.Set(); // <------
Socket s = (Socket)iar.AsyncState;
Socket s2 = s.EndAccept(iar);
SocketStateObject state = new SocketStateObject();
state.workSocket = s2;
s2.BeginReceive(state.buffer, 0, SocketStateObject.BUFFER_SIZE, 0,
new AsyncCallback(Read), state);
}
The callback will executed by a random thread from the pool, but allDone will be set before anything is actually done. It's entirely possible for your Run() loop to run again in the first thread before the work in AcceptCon actually completes. This will cause you big problems.
You should set allDone after you've performed your initialization (and especially after you've accessed any non-threadsafe class members), like so:
private void AcceptCon(IAsyncResult iar)
{
Socket s = (Socket)iar.AsyncState;
Socket s2 = s.EndAccept(iar);
SocketStateObject state = new SocketStateObject();
state.workSocket = s2;
allDone.Set(); // <------
s2.BeginReceive(state.buffer, 0, SocketStateObject.BUFFER_SIZE, 0,
new AsyncCallback(Read), state);
}