私は現在、クライアントがログインできるようにするUDPアプリケーションをプログラミングしています。その後、エンドポイントはリストに格納されます。UDPとポートのランダム化
private void socket_Callback(IAsyncResult result_)
{
EndPoint remote = new IPEndPoint(IPAddress.Any, 0);
socket.EndReceiveFrom(result_, ref remote);
if (!listOfEndPoints.Contains(remote))
{
// registration process
// add it to list
listOfEndPoints.Add(remote)
}
else
{
// process packet
}
}
ただし、クライアントのNATによって、すべてのパケットに異なる外部エンドポイントが割り当てられることがあります。登録パケットのソースエンドポイントが12.34.56.78:1000の場合、そのエンドポイントはリストに追加されます。しかし、同じクライアントが別のパケットを送信した場合、NATはそれを別のポートに割り当てるため、そのソースエンドポイントは12.34.56.78:1001になります。 この結果、サーバーはクライアントが登録されていないと見なし、パケットを登録サーバーとして処理しようとします。言うまでもなく、これはうまくいきません。
これを修正する方法は、IDを送信することです(ただし、超暗号でない場合は簡単に偽造することができます)。ただし、クライアントはサーバーに送信する各パケットにそれを追加する必要があります。 そのようにするのはあまり効果的ではありません。
パケットが登録パケットと同じクライアントから送信されたことを伝える他の方法はありますか。
ありがとうございます!私のコードのバグだったら、なぜパケットのエンドポイントを使わないのですか?それはすべてのクライアントのためにユニークではないだろうか?そして、安全なチェックサムはどのように見えるでしょうか?私は登録時に乱数をクライアントに送ることを考えていました。クライアントはパケットにmd5(パケットデータXORチェックサム)を追加します。サーバーは、チェックサムの正しさをチェックします。あなたはそれが意味することでしたか? – haiyyu
@haiyyu:エンドポイントデータを使用しない理由は、相手先のIPアドレスが変更される可能性があるためです。 TCPでは、ネットワークがパケットをセッションに関連付ける必要があり、NATデバイスはIPを保持することを知っている必要があります。 UDPでは、そうではありません。そして、はい、それは私が意味するもののようなものです。もちろん、最適なソリューションは要件によって異なります。 –