2009-10-09 55 views
2

我在想如何在unix中實現tcp/ip通信。當你通過套接字發送數據時,tcp/level是否工作(彙編數據包,crc等)在與調用代碼相同的執行上下文中執行?unix網絡進程

或者,似乎更有可能,一條消息被髮送到負責tcp通信的其他一些守護進程?這個過程然後接收消息並執行復制內存緩衝區和組裝數據包等請求的工作。所以,調用代碼馬上恢復執行,tcp工作是並行完成的?它是否正確?

詳情將不勝感激。謝謝!

回答

1

TCP/IP stack是你kernel的一部分。發生什麼事是你打電話給準備「kernel trap」的幫手方法。這是一種特殊的例外,它使CPU進入具有更多特權的模式(「內核模式」)。在陷阱內部,內核檢查異常的參數。其中一個是要調用的函數的編號。

當函數被調用時,它將數據複製到內核緩衝區中並準備處理數據的所有內容。然後它從陷阱中返回,CPU恢復寄存器及其原始模式並繼續執行代碼。

一些內核thread會拿起數據的副本,並使用網絡驅動程序發送出去,做所有的錯誤處理等

所以,是的,複製必要的數據後,你的代碼簡歷並且實際的數據傳輸並行發生。

請注意,這是用於TCP數據包。 TCP協議爲你做了所有的錯誤處理和握手,所以你可以給它所有的數據,它會知道該怎麼做。如果連接出現問題,由於TCP協議本身可以處理短暫的網絡中斷,因此只會在一段時間後纔會注意到。這意味着在發生錯誤之前,您已經「發送」了一些數據。這意味着只有在第N次呼叫send()或嘗試關閉連接(close()將掛起,直到接收方已確認所有數據包)之後,您纔會收到第一個數據包的錯誤代碼。

UDP協議不會緩衝。當呼叫返回時,數據包就在路上。但它是「火和忘記」,所以你只知道司機把它放在電線上。如果你想知道它是否到達某個地方,你必須找出一個方法來實現你自己。通常的做法是讓接收方發送一個ack UDP數據包(也可能會丟失)。

+0

謝謝,正是我需要知道的! – rsinha 2009-10-09 18:17:33

0

否 - 沒有並行執行。確實,進行系統調用時的執行上下文與通常的執行上下文不同。當你進行系統調用時,比如通過網絡發送數據包,你必須切換到內核的上下文 - 內核自己的內存映射和堆棧,而不是你在進程中獲得的虛擬內存。

但是沒有守護進程神奇地調度你的呼叫。程序執行的其餘部分必須等待系統調用完成並返回將返回的任何值。這就是爲什麼當你從系統調用中返回時,你可以立即返回可用的返回值 - 例如實際從套接字讀取或寫入文件的字節數。

我試圖找到一個很好的解釋,如何切換到內核空間的上下文工作。這裏是一個不錯的深入其中,即使是專注於特定架構的實現:

http://www.ibm.com/developerworks/linux/library/l-system-calls/

+0

雖然對send()的調用不會立即返回,但它會在數據出現在連線之前返回。所以它並行發送應用程序代碼的執行。 – 2009-10-09 09:00:03

+0

嗯,好點,亞倫。我想答案是:這很複雜。一些工作馬上就會發生,有些工作會在稍後發生,與您自己的代碼並行。所以我明確的'不'是錯誤的。 – 2009-10-09 09:20:38

+0

@Igor目前正在閱讀Richard W. Stevens的「unix網絡編程」,我只是同意Aaron的回答。內核爲您執行所有TCP資料(用於您的應用程序),例如在超時後重新發送未確認的paquet;讓我們繼續前進:與此同時,如果達到完整的TCP窗口大小,所有來自應用程序的新send()函數實際上可能會緩衝數據。 (我可能不完全正確,我自己也不是tcp guru,但這個想法在這裏..)-1。 – 2009-10-09 09:24:39