2012-07-12 160 views
4

我正在Linux上編寫C++應用程序。我的應用程序有一個UDP服務器,它在某些事件中向客戶端發送數據。 UDP服務器還收到來自客戶端的一些反饋/確認。UDP服務器套接字緩衝區溢出

爲了實現這個應用程序,我使用了一個UDP套接字(例如int fdSocket)來發送和接收來自所有客戶端的數據。我將這個socked綁定到端口8080,並將套接字設置爲NON_BLOCKING模式。

我創建了兩個線程。在一個線程中,我等待一些事件發生,如果發生事件,那麼我使用fdsocket向所有客戶端發送數據(在for循環中)。

在另一個線程中,我使用fdSocket接收來自客戶端的數據(recvfrom())。這個線程計劃每4秒運行一次(即每4秒鐘會調用recvfrom()從套接字緩衝區中檢索數據,因爲它處於非阻塞模式,所以如果沒有可用的UDP數據,recvfrom()函數將立即返回,然後I會睡4秒)。

來自所有客戶端的UDP反饋/確認具有大小爲20字節的固定有效載荷。

現在我有兩個與此相關的實施問題:

  1. 它是正確的用於發送/接收UDP數據 與Mulitiple客戶同一插座?
  2. 如何查找UDP反饋/確認數據包的最大數量,我的應用程序可以在沒有UDP套接字緩衝區溢出的情況下處理(因爲我每4秒讀取一次,如果我在這4秒內接收到大量數據包,我可能會丟失一些數據包即ie 。,我需要找到我能安全處理的數據包/秒的速率)?

我嘗試使用函數調用getsockopt(fdsocket,SOL_SOCKET,SO_RCVBUF,(void *)&n, &m);獲取我的套接字(fdsocket)的Linux套接字緩衝區大小。從這個函數中我發現我的Socket緩衝區大小是110592.但是我不清楚這個數據將被存儲在這個套接字緩衝區中:它將只存儲UDP Payload還是整個UDP數據包或事件整個以太網數據包?我提到這個link有一些想法,但感到困惑。

目前我的代碼有點髒,我會在這裏清理併發布它。

以下是發佈此問題前提及的鏈接。

  1. Linux Networking
  2. UDP SentTo and Recvfrom Max Buffer Size
  3. UDP Socket Buffer Overflow Detection
  4. UDP broadcast and unicast through the same socket?
  5. Sending from the same UDP socket in multiple threads
  6. How to flush Input Buffer of an UDP Socket in C?
  7. How to find the socket buffer size of linux
  8. How do I get amount of queued data for UDP socket?
+1

爲什麼只有每4秒?爲什麼不只是讓這個線程坐在一個'select()'調用等待數據? – Collin 2012-07-12 12:17:20

+0

@Collin由於UDP不可靠,我們實現了以下機制。對於發送給客戶端的每個UDP數據包,我都希望從客戶端返回一個確認數據包(帶有固定字符串的簡單UDP數據包)。如果我沒有收到來自客戶端的確認數據包,那麼我將在4秒後再次發送數據包 – 2012-07-12 12:26:34

+1

好吧,但是使用該設置,服務器即使在沒有數據包時也會丟失數據包。在客戶端讀取套接字之後發送數據包時會發生什麼?隨着網絡時間的推移,服務器會認爲即使存在,也不會有任何迴應。仍然沒有理由不立即迴應。您可以使用TCP或類似的東西來代替滾動自己的可靠性:http://udt.sourceforge.net/ – Collin 2012-07-12 12:40:20

回答

3

以4秒的固定時間間隔讀取套接字,絕對會讓您丟失數據包。傳統的非阻塞式I/O的嘗試性方法是解複用器系統調用select(2)/poll(2)/epoll(7)。看看你是否可以使用這些來捕捉/反應你的其他事件。

另一方面,由於您已經在使用線程,因此您可以在沒有四秒睡眠的情況下阻止recv(2)

閱讀Stevens以獲取SO_RCVBUF的解釋。

+0

以及此發佈的評論[EJP](http://stackoverflow.com/users/207421/ejp)給出了一個清晰的想法。 – 2012-07-13 05:31:47

2

問:在Mulitiple客戶端使用相同的套接字發送/接收UDP數據是否正確?答:是的,這是正確的。如何在沒有UDP套接字緩衝區溢出的情況下處理我的應用程序可以處理的UDP反饋/確認數據包的最大數量(因爲我每隔4秒讀取數據,如果在此4秒內收到大量數據包,我可能會丟失一些數據包即,我需要找到費率:我可以安全處理的noofpackets/sec)?

答:瓶頸可能是網絡帶寬或CPU或內存。你可以簡單地做一個測試,使用一個客戶端,用連續的號碼向服務器發送ACK,並驗證服務器是否有數據包丟失。

2

你可以看到允許的最大緩衝區大小:

sysctl net.core.rmem_max 

您可以設置可以使用的最大緩衝區大小:

sysctl -w net.core.rmem_max=8388608 

您還可以設置在運行時的緩衝區大小(不超過上述最大值),方法是使用setsockopt並更改SO_RCVBUF。您可以通過查看/ proc/net/udp來查看緩衝區級別。

緩衝區用於存儲UDP標頭和應用程序數據,其餘屬於較低級別。