2014-02-17 85 views
3
socketFd_ = socket(AF_INET, SOCK_RAW, protoType);  
sentBytes = sendto(socketFd_, buf, len, 0, 
        (struct sockaddr *)&sa,sizeof(structsockaddr_in)); 
protoType = GRE 

我正在網絡中發送1000個數據包。 如果我的tx數據包速率是40,我能夠看到wireshark中的所有數據包。 但是,當我嘗試以100的速率發送某些數據包(3-4)時,無法在網絡中發送,但sendto不會返回任何錯誤。 我知道sendto只會將txpacket放入隊列中,並不保證在網絡中傳送數據包,但是從哪裏可以獲得丟棄數據包的統計信息以及數據包在內核中的丟棄原因。 我曾嘗試將接口的txqueuelen增加到65000,但它沒有幫助。 我該如何調試這個問題?rawsocket sendto()某些數據包被丟棄並且在網絡中看不到

+0

我試圖檢查發送緩衝區的大小: getsockopt(socketFd_,SOL_SOCKET,SO_SNDBUF,&sendBuffSize,&buffLen); 它顯示了一個很大的值sendBuffSize = 124928, 我觀察到系統調用sendto()達到2040後我的掛起緩衝區大小,它會丟棄數據包(sendto在這裏成功返回),我正在檢查未完成的sendto緩衝區大小使用 ioctl(socketFd_,SIOCOUTQ,&outstandingBytes); 我的問題是爲什麼sendto沒有返回任何錯誤?是因爲sendBuffSize大於outstandingBytes? 任何人都可以幫助我調試這個問題? 謝謝 – devesh

+0

sendto之後的另一個測試場景如果在再次調用sendto之前我會等待outstatndingBytes達到零,系統中不會有任何數據包丟失 – devesh

回答

1

你是對的,sendto只會將txpacket放入隊列中,不保證傳送。

從上SENDTO的IEEE文件:向SENDTO呼叫

成功完成()並不能保證郵件的傳遞。返回值-1表示只有本地檢測到的錯誤。

你必須通過ioctl()和getsockopt()來執行一些你自己的節流,就像你幾乎要做的那樣。我不認爲你可以指望網絡堆棧爲你做這一切。

喜歡的東西:

sendMsgThrottled(msg Msg) { 
    ioctl(socketFd_, SIOCOUTQ, &outstandingBytes); 
    if (outStandingBytes < limit) 
      sendto(socketFd_, ..) 
    else 
      queueMsg(); /* Or delay */ 
} 

我會首先與由同一臺機器上發送和接收器測試,數據包丟失可能來自除操作系統的網絡層等地。

+0

在每次sendto之後調用系統調用ioctl將會導致性能下降,但是我擔心的是這是爲什麼包在丟失比特率達到2040時被丟棄的原因,我如何增加這個限制。 我的發送緩衝區大小是124928我得到這個值使用getsockopt()SO_SNDBUF選項。 – devesh

+0

你發送的數據包的大小是多少?那麼速率是40 /秒? ioctl()通常不是一個很大的性能影響。 –

+0

數據包的大小將是326字節,我觀察到這個問題時,我將以400包/秒的速率發送, 從我看到的wireshark在150微秒內,我將注入10個數據包到網絡中。類型的小突發,我會打電話給一個1毫秒的定時器,週期性地注入突發數據包的速率) – devesh