TCP/IP協議棧是網絡中廣泛使用的事實網絡通信標準。最初的TCP實現源自4.4BSD lite,在Linux興起后,也不可避免得支持它。但Linux的實現自成體系,僅與傳統實現保持接口上的兼容,下面我們將針對源碼級的實現,來分析一下兩者的異同。但是,對于Linux和FreeBSD這樣優秀的系統來說,已經無所謂何優何劣,有的僅僅是實現策略與側重點上的不同而已。
從進程的角度上講,可以調用send,sendto,sendmsg來發送一段數據,來可以使用文件系統中的write和writev來發送數據。同理,接收數據可以使用相應的recv,recvmsg,recvfrom,也可以使用文件系統提供的read,readv來接收一段數據。對于接收來說,這是異步進行的,也就是說,這是中斷驅動的,在以后的分析中,我們要注意這點。為簡單起見,同時不失一般性,我們將分析TCP協議的輸入輸出全過程,并以已對LINUX及FreeBSD的實現作一對比。
首先我們來看FreeBSD上的協議實現,這也是最正統的實現。下面是完整的輸入輸出路徑。
首先來看左邊的輸出,不管應用程序調用哪個輸出函數,最終都要調用sosend來完成輸出。Sosend將從用戶空間把數據復制進內核管理的m_buf數據結構,m_buf是FreeBSD的TCP實現使用的數據緩沖結構。在sosend完成數據復制后,將調用TCP的輸出函數,tcp_output要做的事情是分配一個新的m_buf來保存tcp頭,并計算相應的數據校驗碼,在下一步的ip_output中,同樣也要進行數據校驗工作,并進行數據路由選擇。最終ether_output將通過if_start來調用具體的硬件驅動程序來完成數據發送。在某個網卡的驅動中,ex_start將負責將數據從內核的m_buf緩沖復制進硬件自己的緩沖區,以完成數據發送工作。在這整個過程中,數據被復制兩次,并且也被遍歷兩次(計算校驗碼),這也是主要的影響效率的地方。