8

これまでUDPを使用したことがなかったので、試してみました。何が起こるかを確認するために、「サーバー」に0.5秒ごとにデータを送信させ、クライアントに3秒ごとにデータを受信させました。したがって、サーバーはクライアントが受信できるよりもはるかに高速にデータを送信しますが、クライアントはそれでもすべてを1つずつきちんと受信します。

なぜ/どのようにこれが起こるのか誰かが説明できますか?データは正確にどこにバッファリングされますか?

送信

class CSimpleSend
{
    CSomeObjServer obj = new CSomeObjServer();

    public CSimpleSend()
    {
        obj.changedVar = varUpdated;
        obj.threadedChangeSomeVar();
    }

    private void varUpdated(int var)
    {
        string send = var.ToString();
        byte[] packetData = System.Text.UTF8Encoding.UTF8.GetBytes(send);

        string ip = "127.0.0.1";
        int port = 11000;

        IPEndPoint ep = new IPEndPoint(IPAddress.Parse(ip), port);
        Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        client.SendTo(packetData, ep);

        Console.WriteLine("Sent Message: " + send);
        Thread.Sleep(100);
    }
}

CSomeObjServerが行うのは、0.5秒ごとに1ずつ整数をインクリメントすることだけです。

受け取る

class CSimpleReceive
{
    CSomeObjClient obj = new CSomeObjClient();

    public Action<string> showMessage;
    Int32 port = 11000;
    UdpClient udpClient;


    public CSimpleReceive()
    {
        udpClient = new UdpClient(port);

        showMessage = Console.WriteLine;
        Thread t = new Thread(() => ReceiveMessage());
        t.Start();
    }

    private void ReceiveMessage()
    {                      
        while (true)
        {
            //Thread.Sleep(1000);
            IPEndPoint remoteIPEndPoint = new IPEndPoint(IPAddress.Any, port);
            byte[] content = udpClient.Receive(ref remoteIPEndPoint);

            if (content.Length > 0)
            {
                string message = Encoding.UTF8.GetString(content);
                if (showMessage != null)
                    showMessage("Recv:" + message);

                int var_out = -1;
                bool succ = Int32.TryParse(message, out var_out);
                if (succ)
                {
                    obj.alterSomeVar(var_out);
                    Console.WriteLine("Altered var to :" + var_out);
                }
            }
            Thread.Sleep(3000);
        }
    }
}

CSomeObjClientは変数を格納し、それを更新するための1つの関数(alterSomeVar)を持っています

Ouput:

Sent Message: 1
Recv:1
Altered var to :1
Sent Message: 2
Sent Message: 3
Sent Message: 4
Sent Message: 5
Recv:2
Altered var to :2
Sent Message: 6
Sent Message: 7
Sent Message: 8
Sent Message: 9
Sent Message: 10
Recv:3
Altered var to :3
4

2 に答える 2

3

オペレーティングシステムカーネルは、UDPおよびTCPソケットごとに個別の送信バッファと受信バッファを維持します。あなたがグーグルSO_SNDBUFして、SO_RCVBUFあなたがそれらについてのたくさんの情報を見つけるならば。

データを送信すると、データはアプリケーションスペースから送信バッファにコピーされます。そこからネットワークインターフェイスカードにコピーされ、次にネットワークにコピーされます。受信側は逆です。NICはバッファを受信し、読み取りまで待機します。さらに、OSによっては、コピーとバッファリングも発生する可能性があります。

これらのバッファのサイズは大幅に異なる可能性があることに注意することが重要です。一部のシステムはデフォルトでわずか4キロバイトに設定されている場合がありますが、他のシステムでは2メガバイトになります。またはを使用getsockopt()して現在のサイズを検索し、同様にを使用して設定できます。ただし、多くのシステムでは、バッファのサイズが制限されており、場合によっては任意の少量に制限されています。これは通常、またはのようなカーネル値ですが、正確な参照はシステムによって異なります。SO_SNDBUFSO_RCVBUFsetsockopt()net.core.wmem_maxnet.core.rmem_max

setsockopt()また、想定される制限より少ない金額をリクエストしても失敗する可能性があることに注意してください。setsockopt()したがって、実際に目的のサイズを取得するには、最終的に成功するまで、減少する量を使用して繰り返し呼び出す必要があります。

次のページは、このトピックに少し触れ、いくつかの一般的なシステムのリファレンスを提供する、私の会社のテクニカルノートです。http ://www.dataexpedition.com/support/notes/tn0024.html

于 2012-09-12T17:12:13.637 に答える
0

UdpClient-Class が受信データのバッファを提供しているように見えます。ソケットを直接使用してみてください。TCP接続にのみ使用されると思われますが、ソケットのReceiveBufferSizeをゼロに設定することもできます。

于 2012-09-06T12:28:03.960 に答える