0

8 バイトのデータをできるだけ速く受信するように、非常に単純な UdpClient をセットアップしました。クライアントはデータを非常に高速に送信していますが、サーバーは約 0.5 秒という非常に不安定な間隔でデータを受信して​​います。受信時に停止し、突然約 10 個のデータグラムを連続して非常に高速に受信し、再び約 0.5 秒間停止します。ここで何が問題になる可能性がありますか?ファイアウォールをオフにしてみましたが、効果がありませんでした...

クライアント:

_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

このコードは、蓄積されたバッファを継続的に送信しています。

if (!_sending)
{
    _sending = true;

    SocketAsyncEventArgs args = new SocketAsyncEventArgs();

    args.Completed += (s2, e2) => { _sending = false; };
    args.RemoteEndPoint = new IPEndPoint(IPAddress.Parse("192.168.0.100"), 14123);
    args.SetBuffer(buffer, 0, buffer.Length);

    _socket.SendToAsync(args);
}

サーバ:

    UdpClient udp = new UdpClient(new IPEndPoint(IPAddress.Parse("192.168.0.100"), 14123));
    IPEndPoint endpoint = new IPEndPoint(IPAddress.Any, 0);

    while (true)
    {
        byte[] buffer = udp.Receive(ref endpoint);
        int x = BitConverter.ToInt32(buffer, 0);
        int y = BitConverter.ToInt32(buffer, 4);
        Console.WriteLine(string.Format("Receiving x={0}, y={1} @ {2}", x, y, DateTime.Now.Ticks));
    }

私は今、その非常に原始的なコードを知っていますが、少なくとも例外をスローしていません...

Wiresharkで確認しましたが、何を探すべきか正確にはわかりません. UDP メッセージは問題なく送信されます。

UDPを抑制し、できるだけ速く送信しないことをお勧めします。私は目立った違いなしでそれを試しました。送信は遅くなりますが、受信は以前と同じくらいチャンキー/バーストです。

クライアントとレシーバーの両方が同じ開発マシン (Windows 7) 上にあります。


Receive-call 間の時間 (秒) を測定した結果の出力を次に示します。ご覧のとおり、約 30 回の反復ごとに 1 秒間スタックします。

1,0180582
0,001
0
0
0,0010001
0
0
0
0
0,0010001
0
0
0
0
0
0
0
0
0
0
0,0010001
0
0
0
0
0
0,0010001
1,0170582

アップデート

バッファが送信された後に遅延が発生したようです。送信コードはバッファを非常に迅速/流動的に送信しているように見えますが、Wireshark に表示されると、udp 起動の約 1 秒ごとに 1 秒の遅延があります。受信側のコードがこの遅延を引き起こしているようには見えませんが、既に存在しています。理解できません。

4

1 に答える 1

1

.Net 非同期 I/O を使用することで、送信タイミングの制御を放棄しているように思えます。この非同期機能に組み込まれている遅延の種類はわかりませんが、バックグラウンド スレッド プールが関係しており、それらのスレッドが入力キューをポーリングしていると推測されます。

そのオーバーヘッドをすべて回避し、同じスレッドで送信するだけに対処したいと思います。UDP は非常に単純です。特に単一のソケットを扱う場合は、送信して忘れるだけです。ここでは、非同期 I/O オーバーヘッドは必要ないと思います。

于 2011-08-05T12:44:53.260 に答える