2

C# の起動時間が遅いため、UDP パケットが最初にドロップするという問題が発生しました。以下は、この起動遅延を軽減するために行ったことです。基本的に、最初の 2 つのパケット送信の間にさらに 10 ミリ秒待ちます。これにより、少なくとも私のマシンでは最初のドロップが修正されます。私の懸念は、遅いマシンではこれよりも長い遅延が必要になる可能性があることです。

private void FlushPacketsToNetwork()
{
    MemoryStream packetStream = new MemoryStream();

    while (packetQ.Count != 0)
    {
        byte[] packetBytes = packetQ.Dequeue().ToArray();
        packetStream.Write(packetBytes, 0, packetBytes.Length);
    }

    byte[] txArray = packetStream.ToArray();
    udpSocket.Send(txArray);

    txCount++;

    ExecuteStartupDelay();
}

// socket takes too long to transmit unless I give it some time to "warm up"
private void ExecuteStartupDelay()
{
    if (txCount < 3)
    {
        timer.SpinWait(10e-3);
    }
}

では、C# にすべての依存関係を完全にロードさせるためのより良いアプローチがあるのではないかと考えています。完全にロードするのに数秒かかるかどうかは気にしません。C# がフル スピードの準備が整うまで、高帯域幅の送信を行いたくありません。

追加の関連詳細

これはコンソール アプリケーションであり、ネットワーク転送は別のスレッドから実行され、メイン スレッドはキーが押されてネットワーク トランスミッタが終了するのを待つだけです。

このProgram.Main方法では、妥当な最高の優先順位を使用して、アプリケーションから最大のパフォーマンスを得ようとしました。

public static void Main(string[] args)
{
    Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High;
    ...
    Thread workerThread = new Thread(new ThreadStart(worker.Run));
    workerThread.Priority = ThreadPriority.Highest;
    workerThread.Start();
    ...
    Console.WriteLine("Press any key to stop the stream...");
    WaitForKeyPress();

    worker.RequestStop = true;
    workerThread.Join();

また、現在使用しているソケット設定を以下に示します。

udpSocket = new Socket(targetEndPoint.Address.AddressFamily,
                       SocketType.Dgram,
                       ProtocolType.Udp);
udpSocket.Ttl = ttl;
udpSocket.SendBufferSize = 1024 * 1024;
udpSocket.Blocking = true;

udpSocket.Connect(targetEndPoint);

デフォルトSendBufferSizeは 8192 なので、思い切って 1 メガバイトまで上げてみましたが、この設定は最初はドロップされたパケットに影響を与えていないようでした。

4

1 に答える 1

0

コメントから、(送信に固有の遅延があるため) TCP はオプションではないことがわかりました。また、相手側が完全にロードされていないためにパケットを失いたくありません。

したがって、実際には TCP (再送信) に存在するいくつかの機能を実装する必要がありますが、より堅牢で軽量な方法で実装する必要があります。また、受信側を制御していると仮定します。

事前に決められた数のパケットを送信することを提案します。そして、確認を待ちます。たとえば、すべてのパケットは、常に大きくなる ID を持つことができます。N パケットごとに、受信アプリケーションは最後に受信したパケットの番号を送信者に送信します。この数を受信した後、送信者は最後の N パケットを繰り返す必要があるかどうかを認識します。

この方法で帯域幅が大きく損なわれることはなく、受信したデータに関する何らかの情報が得られます (保証はされていません)。

それ以外の場合は、TCP に切り替えることをお勧めします。ところで、TCP を使ってみましたか?それが原因で、帯域幅はどの程度損なわれますか?

于 2012-05-29T18:07:07.800 に答える