2012-09-06 83 views
8

我以前從未使用UDP,所以我放棄了它。爲了看看會發生什麼,我讓「服務器」每半秒發送一次數據,客戶端每3秒收到一次數據。因此,即使服務器發送數據的速度比客戶端可以接收的速度快得多,客戶端仍然可以一個接一個地整齊地接收數據。UDP存儲的數據在哪裏?

任何人都可以解釋爲什麼/這是怎麼發生的?數據在哪裏準確緩衝?

發送

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確實是增加一個整數由一個每半秒

接收

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存儲變量和具有一個功能(alterSomeVar)來更新它

輸出繼電器:

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 
+3

我舉雙手贊成你的好奇本性,+1 – spender

+1

操作系統具有網絡棧通常有一些緩衝區......只要你發送的內容適合這些緩衝區沒有問題...因爲UDP不能保證無論如何數據可能被丟棄等。 – Yahia

+0

客戶端和服務器是否在同一臺機器上運行? – grieve

回答

3

操作系統內核爲每個UDP和TCP套接字維護單獨的發送和接收緩衝區。如果你谷歌SO_SNDBUFSO_RCVBUF你會發現很多關於他們的信息。

當您發送數據時,它會從應用程序空間複製到發送緩衝區中。從那裏它被複制到網絡接口卡,然後到網絡上。接收端是相反的:NIC接收緩衝區,等待您讀取它。此外,還可能發生複製和緩衝,具體取決於操作系統。

請注意,這些緩衝區的大小可能會發生根本性的變化。某些系統可能默認只有4千字節,而其他系統可能會給你2兆字節。您可以使用getsockopt()SO_SNDBUFSO_RCVBUF找到當前尺寸,並使用setsockopt()同樣設置它。但是很多系統會限制緩衝區的大小,有時會限制到任意小的數量。這通常是一個內核值,如net.core.wmem_maxnet.core.rmem_max,但確切參考會因系統而異。

另請注意,setsockopt()可能會失敗,即使您請求的金額小於假定的限制。因此,要真正獲得所需的尺寸,您需要使用遞減的數量重複呼叫setsockopt(),直到它最終成功。

下面的頁面是從我公司技術說明它在這個題目倒是一點點,對於一些常見的系統提供了參考:http://www.dataexpedition.com/support/notes/tn0024.html

+0

很好的答案,謝謝! – natli

0

在我看來像UdpClient級提供了一種用於接收數據的緩衝器。嘗試直接使用套接字。您可能還想將套接字ReceiveBufferSize設置爲零,即使我相信它僅用於TCP連接。