Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where is data sent by UDP stored?

Tags:

c#

udp

I had never used UDP before, so I gave it a go. To see what would happen, I had the 'server' send data every half a second, and the client receive data every 3 seconds. So even though the server is sending data much faster than the client can receive, the client still receives it all neatly one by one.

Can anyone explain why/how this happens? Where is the data buffered exactly?

Send

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);
    }
}

All CSomeObjServer does is increment an integer by one every half second

Receive

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 stores the variable and has one function (alterSomeVar) to update it

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
like image 810
natli Avatar asked Sep 06 '12 12:09

natli


1 Answers

The operating system kernel maintains separate send and receive buffers for each UDP and TCP socket. If you google SO_SNDBUF and SO_RCVBUF you'll find lots of information about them.

When you send data, it is copied from your application space into the send buffer. From there it is copied to the network interface card, and then onto the wire. The receive side is the reverse: NIC to receive buffer, where it waits until you read it. Additionally copies and buffering can also occur, depending on the OS.

It is critical to note that the sizes of these buffers can vary radically. Some systems might default to as little as 4 kilobytes, while others give you 2 megabytes. You can find the current size using getsockopt() with SO_SNDBUF or SO_RCVBUF and likewise set it using setsockopt(). But many systems limit the size of the buffer, sometimes to arbitrarily small amounts. This is typically a kernel value like net.core.wmem_max or net.core.rmem_max, but the exact reference will vary by system.

Also note that setsockopt() can fail even if you request an amount less than the supposed limit. So to actually get a desired size, you need to repeatedly call setsockopt() using decreasing amounts until it finally succeeds.

The following page is a Tech Note from my company which touches on this topic a little bit and provides references for some common systems: http://www.dataexpedition.com/support/notes/tn0024.html

like image 66
Seth Noble Avatar answered Nov 15 '22 06:11

Seth Noble