簡體   English   中英

UDP服務器套接字緩沖區溢出

[英]UDP Server Socket Buffer Overflow

我正在Linux上編寫C ++應用程序。 我的應用程序有一個UDP服務器,它在某些事件上向客戶端發送數據。 UDP服務器還從客戶端接收一些反饋/確認。

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

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

在另一個線程中,我使用fdSocket從客戶端接收數據( recvfrom() )。 該線程計划每4秒運行一次(即每4秒調用一次recvfrom()以從套接字緩沖區中檢索數據。由於它處於NON-BLOCKING模式,如果沒有UDP數據, recvfrom()函數將立即返回可用,然后我會睡4秒)。

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

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

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

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

目前我的代碼有點臟,我會在這里清理並發布。

以下是我在發布此問題之前提到的鏈接。

  1. Linux網絡
  2. UDP SentTo和Recvfrom最大緩沖區大小
  3. UDP套接字緩沖區溢出檢測
  4. UDP通過同一個套接字廣播和單播?
  5. 從多個線程中的相同UDP套接字發送
  6. 如何在C中刷新UDP套接字的輸入緩沖區?
  7. 如何找到linux的socket緩沖區大小
  8. 如何獲取UDP套接字的排隊數據量?

以4秒的固定間隔讀取套接字肯定會讓您丟失數據包。 對於非阻塞I / O的傳統的經過驗證的方法是解復用器系統調用select(2) / poll(2) / epoll(7) 看看你是否可以使用這些來捕捉/回應你的其他事件。

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

閱讀史蒂文斯SO_RCVBUF解釋。

問:使用相同的套接字與Mulitiple客戶端發送/接收UDP數據是否正確?

答:是的,這是對的。

問:如何在沒有UDP套接字緩沖區溢出的情況下找到我的應用程序可以處理的UDP反饋/確認數據包的最大數量(因為我每4秒讀取一次,如果我在這4秒內收到大量數據包,我可能會丟失一些數據包,即。,I需要找到率:noofpackets / sec我可以安全處理)?

答:瓶頸可能是網絡帶寬,CPU或內存。 您可以使用向連續編號的服務器發送ACK的客戶端進行測試,並驗證服務器是否有丟包。

您可以看到允許的最大緩沖區大小:

sysctl net.core.rmem_max

您可以通過以下方式設置可以使用的最大緩沖區大小:

sysctl -w net.core.rmem_max=8388608

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM