多くのクライアントを管理するサーバー側アプリケーションを作成しました。すべては、BeginSend() および EndSend() メソッドを使用して非同期で行われます。
場合によっては、クライアントの 1 つに 2 つの後続の要求を送信する必要があります。最初のBeginSend() と最後のEndSend() の間に新しい BeginSend() が呼び出されないようにしたいと考えています。サーバーがクライアントに2つのメッセージを送信しようとすると、最初のメッセージが送信されるまで2番目のメッセージがブロックされるように、AutomaticResetEventでこれを行うことについて考えました
- これは上記の方法でそれを行う意味がありますか?
- コードブローは、「NullReferenceException」をスローすることがあります。そして、私はその理由を理解できないようですか?
洞察をありがとう。
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;
}
}
public void SendAsyncData(string str, CommandsToClient cmd)
{
byte[] data = Combine(BitConverter.GetBytes((int)(cmd)), BitConverter.GetBytes((int)(str.Length)), Encoding.ASCII.GetBytes(str));
SendAutoResetEvent.WaitOne();
SendAsyncDataWithHeader(data);
}
private void SendAsyncDataWithHeader(byte[] data)
{
int toSend;
byte[] dataWithHeader = Combine(BitConverter.GetBytes(data.Length), data);
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)
{
Disconnected(this);
}
}
void sendCallback(IAsyncResult ar)
{
try
{
int bytesSent = socket.EndSend(ar);
if (bytesSent == 0)
{
if (Disconnected != null)
{
Disconnected(this);
return;
}
}
sendBuffer.sent += bytesSent;
if (sendBuffer.sent == sendBuffer.BUFFER.Length)
{
//all data was sent. do some
//do some processing...
sendBuffer.Dispose();
//let new send request in
SendAutoResetEvent.Set();
return;
}
int toSend;
// exception says that in the following line, sendBuffer.Buffer is null....
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 (NullReferenceException ex)
{
//here an exception is thrown,
}
catch (Exception ex)
{
Disconnected(this);
}
}
}
}