2008-11-03 50 views
5

我有一個不尋常的情況:我在嵌入式情況下使用Linux系統(目前使用2.6.20內核的英特爾盒),它必須與具有部分中斷的TCP實現的嵌入式系統進行通信。就在我現在可以告訴他們的情況下,他們希望來自我們的每條消息都來自單獨的以太網幀!當消息分散在以太網幀中時,它們似乎有問題。我需要一個TCP選項(ioctl)立即發送數據

我們在設備的本地網絡上,我們之間沒有路由器(只是一個交換機)。

當然,我們正試圖迫使他們修復他們的系統,但這可能不會結束。

我已經在我的套接字上設置了TCP_NODELAY(我連接到它們),但是這隻有在我不嘗試一次發送多條消息時纔有用。如果我連續有幾個傳出消息,那麼這些消息往往會以一個或兩個以太網幀結束,這會導致其他系統出現問題。

我通常可以避免使用計時器來避免發送消息太靠近在一起的問題,但這顯然限制了我們的吞吐量。此外,如果我把時間降得太低,我就會冒着網絡擁塞阻止數據包傳輸,並最終允許我的多條消息進入同一個數據包。

有什麼辦法可以判斷驅動程序是否有數據排隊?有什麼辦法可以強制驅動程序在獨立的傳輸層數據包中發送獨立的寫入調用嗎?我查看了套接字(7)和tcp(7)手冊頁,但沒有發現任何內容。這可能只是我不知道我在找什麼。顯然,UDP將是一種出路,但是,我認爲我們不能在這一點上讓另一端改變任何東西。

任何幫助非常感謝。

回答

7

IIUC,設置TCP_NODELAY選項應該清除所有數據包(即tcp.c通過調用tcp_push_pending_frames來實現NODELAY的設置)。所以如果你在每次發送呼叫後都設置套接字選項,你應該得到你想要的。

1

也許,請設置TCP_NODELAY並將您的MTU設置得足夠低,以便每幀至多有1條消息?哦,並在傳出數據包上添加「dont-fragment」標記

+0

不錯的主意。不幸的是,由於消息的大小不統一,我不能選擇在這種情況下每幀保證一條消息的MTU。 – 2008-11-03 16:41:26

0

您是否曾嘗試爲每條消息打開一個新套接字並立即關閉它?開銷可能會令人噁心,但是這應該劃定您的消息。

+0

不幸的是,這會比分散的消息在另一端造成更多的麻煩,所以在這種情況下它不會起作用。 – 2008-11-03 16:39:52

0

在最糟糕的情況下,您可以降低一個級別(原始套接字),您可以更好地控制發送的數據包,但是您必須處理TCP的所有細節。

-1

也許你可以嘗試把TCP協議棧到低延時模式:

echo 1 > /proc/sys/net/ipv4/tcp_low_latency 

這應該有利於對數據組合起來儘可能快地發出的數據包。閱讀tcp(7)上的man以獲取更多信息。

+0

根據Linux內核(net/ipv4/tcp.c)中的代碼判斷,tcp_low_latency標誌隻影響從TCP堆棧讀取數據到應用程序緩衝區。 – Alexander 2008-11-03 22:12:19

+0

Alexander是對的 – 2012-12-06 08:48:06

2

除非您確定問題出在哪裏,否則您無法解決問題。

如果他們已經做了假設recv()收到完全一個消息的新手錯誤,那麼我沒有看到完全解決它的方法。每個以太網幀僅發送一條消息是一回事,但如果多個以太網幀在接收器調用recv()之前到達,它仍將在一次調用中獲得多條消息。

即使網絡擁塞可以告訴你他們多久會調用recv(),但實際上不可能阻止這種情況(同時保持相當的吞吐量)。