現在、C# で非同期 UDP ネットワーク コードを書いています。私は小さなパケット (これまでのところそれぞれのデータが 50 バイト未満) を送受信していますが、最初に考えたのは、それらを 2 つの異なるパケットに分割し、1 つのパケットとして送信し、2 つのパケットとして受信することでした。したがって、ヘッダーまたは追加情報パケットは、常に実際のパケットの先頭に追加されます。これには、ID とデータ長が含まれます。
そのため、受信側で分割して(非同期受信)、最初にヘッダーを受信し、次に実際の情報を受信できると考えました。これは、パケットと「パケット ヘッダー」の間の順序を気にする必要がないようにするためです。
そこで、基本的に次のように機能するコードを書きました。クライアントは 30 バイトのデータをサーバーに送信します。最初の 3 バイトはパケット ヘッダーです。
サーバーは (PACKET_HEADER_SIZE = 3) を呼び出します。
socket.BeginReceiveFrom(state.Buffer, 0, PACKET_HEADER_SIZE, SocketFlags.None, ref endPoint, ReceivePacketInfo, state);
次に、データを受け取ります。
private void ReceivePacketInfo(IAsyncResult ar)
{
StateObj state = (StateObj) ar.AsyncState;
int bytesRead = socket.EndReceiveFrom(ar, ref endPoint);
state.BytesReceived += read;
if (state.BytesReceived < state.Buffer.Length)
{
_socket.BeginReceiveFrom(state.Buffer, state.BytesReceived, state.Buffer.Length - state.BytesReceived, SocketFlags.None, ref endPoint, ReceivePacketInfo, state);
}
else
{
//my thought was to receive the rest of the packet here
}
}
しかし、socket.EndReceiveFrom(ar) を呼び出すと、SocketException が発生します。
「データグラムソケットで送信されたメッセージが、内部メッセージバッファーまたはその他のネットワーク制限よりも大きかったか、データグラムを受信するために使用されたバッファーがデータグラム自体よりも小さかった」
そこで、いくつか質問があります。
EndReceiveFrom を呼び出す前に、パケット全体 (この場合はヘッダーとパケットの両方) を確実に受信する必要がありますか?
一度にパケット全体を取得するか、何も取得しないため、ReceivePacketInfo の if ステートメントが冗長になると想定できますか (もちろん、サイズが最大パケット サイズ未満である限り)。
できない場合、問題を解決する良い方法はありますか? すべてのパケット ヘッダーとすべてのパケットにタグを付けて、それらを一緒にマッピングできると思います。また、標準化された「パケット終了」を設定して、パケットの最後に到達するまで読むだけにすることもできます。
助けてくれてありがとう!