次のコードを検討してください。
class UPDServer {
//start listener
public void start() {
UdpClient listener = new UdpClient(this._porta);
IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, 10000);
State s = new State();
s.listener = listener;
s.ipEndPoint = ipEndPoint;
// begin to listen again
listener.BeginReceive(new AsyncCallback(ReceiveCallback), s);
}
//receive data
public void ReceiveCallback(IAsyncResult ar)
{
// we got data
State s = (State)(ar.AsyncState);
Byte[] received = e.escuta.EndReceive(ar, ref e.ipEndPoint);
string text = ""; = Encoding.ASCII.GetString(received);
// ... do somenthing with text
// begin to listen again
s.listener.BeginReceive(new AsyncCallback(ReceiveCallback), e);
}
}
上記のコードでは、EndReceive と次の BeginReceive の間に誰もリッスンしていない時間帯があります。この時間帯にメッセージがあると、メッセージは失われると思います。
まあ、何らかのバッファがあると思いますが、それでも、誰もメッセージをリッスンしていない時間帯にバッファがいっぱいになると、メッセージが失われます。
同じエンドポイントでBeginReceiveを数回呼び出すことでこれを非常に簡単に解決できると誰かが言ったことを覚えているので、これを試しました:
for( int x = 0; x < 5;x++) {
escuta.BeginReceive(new AsyncCallback(ReceiveCallback), e);
}
奇妙なことに、同じソケットで begin receive を呼び出してもエラーはスローされませんが、メッセージが受信されるたびに、5 つすべての beginReceive が起動し、5 つすべてが同じメッセージを受け取ります。
コードを改善する方法はありますか?