I've written a serverside application that manages many clients using BeginSend()
and EndSend()
I'm struggling for the past hours to make sure no consequent BeginSend()
calls are called for the same client.
It seems that the following code snippet doesn't achieve my goal and doesn't block on the second call to SendAsyncData
before the first completed.
What is my mistake?
struct SendBuffer
{
public const int BUFFER_SIZE = 1024 * 128;
public byte[] BUFFER;
public int sent;
public SendBuffer(byte[] data)
{
BUFFER = new byte[data.Length];
Buffer.BlockCopy(data, 0, BUFFER, 0, data.Length);
sent = 0;
}
public void Dispose()
{
BUFFER = null;
sent = 0;
}
}
private void SendAsyncDataWithHeader(byte[] data
{
int toSend;
byte[] dataWithHeader = Combine(BitConverter.GetBytes(data.Length), data);
SendAutoResetEvent.WaitOne();
sendBuffer = new SendBuffer(dataWithHeader);
if (sendBuffer.BUFFER.Length - sendBuffer.sent > SendBuffer.BUFFER_SIZE)
toSend = SendBuffer.BUFFER_SIZE;
else
toSend = sendBuffer.BUFFER.Length - sendBuffer.sent;
try
{
socket.BeginSend(sendBuffer.BUFFER, 0, toSend, SocketFlags.None, sendCallback, null);
}
catch (SocketException se)
{
switch (se.SocketErrorCode)
{
case SocketError.ConnectionAborted:
case SocketError.ConnectionReset:
if (Disconnected != null)
{
Disconnected(this);
}
break;
}
}
catch (ObjectDisposedException)
{
}
catch (NullReferenceException ex)
{
}
catch (Exception ex)
{
Server.logger.Error(ex);
Disconnected(this);
}
}
void sendCallback(IAsyncResult ar)
{
int bytesSent;
try
{
bytesSent = socket.EndSend(ar);
if (bytesSent == 0)
{
if (Disconnected != null)
{
Disconnected(this);
return;
}
}
sendBuffer.sent += bytesSent;
if (sendBuffer.sent == sendBuffer.BUFFER.Length)
{
sendBuffer.Dispose();
SendAutoResetEvent.Set();
Server.logger.Info("set {0}", userName);
}
else
{
int toSend;
if (sendBuffer.BUFFER.Length - sendBuffer.sent > SendBuffer.BUFFER_SIZE)
toSend = SendBuffer.BUFFER_SIZE;
else
toSend = sendBuffer.BUFFER.Length - sendBuffer.sent;
socket.BeginSend(sendBuffer.BUFFER, sendBuffer.sent, toSend, SocketFlags.None, sendCallback, null);
}
}
catch (SocketException se)
{
switch (se.SocketErrorCode)
{
case SocketError.ConnectionAborted:
case SocketError.ConnectionReset:
if (Disconnected != null)
{
Disconnected(this);
return;
}
break;
}
}
catch (ObjectDisposedException ex)
{
}
catch (Exception ex)
{
Server.logger.Error(ex);
Disconnected(this);
}
}