《TCP/IP詳解卷2:實現》筆記--TCP的用戶需求

本文介紹TCP的用戶請求處理函數tcp_usrreq,它被協議的pr_usrreq函數調用,處理各種與tcp插口有關的系統調用,此外,

還將介紹tcp_ctloutput,應用進程調用setsockopt設定tcp插口選項時會用到它。

TCP的用戶請求函數用於處理多種操作,主要由tcp_usrreq函數完成,函數的對各個請求的大概處理如下:

1.PRU_ATTACH請求。應用程序調用socket系統調用,或者監聽服務器收到連接其你去,調用sonewconn函數,都會發出

PRU_ATTACH請求。如果插口結構已經指向某個PCB,則返回錯誤,調用tcp_attach完成處理:分配並初始化Internet PCB

和TCP控制塊。

2.PRU_DETACH請求。close系統調用在PRU_DISCONNECT請求失敗後,將發送PRU_DETACH請求,如果尚未建立連接,

則無需向對端發送任何信息,但如果連接已經建立,則調用tcp_disconnect初始化TCP的連接關閉過程。(發送所有緩存中

的數據,之後發送FIN)

3.PRU_BIND請求的處理只是簡單地調用in_pcbbind。

4.對於PRU_LISTEN請求,如果插口還沒有綁定到某個本地端口上,在調用in_pcbbind自動爲其分配一個。連接狀態變遷

到LISTEN,完成了listen調用的主要目的:設定插口的狀態,以便接收到達的連接請求。

5.PRU_CONNECT請求。connect系統調用發起該請求,處理的大概流程如下:

a.分配臨時端口。

b.連接PCB。

c.初始化IP和TCP首部。

d.計算窗口縮放因子。

e.設定插口和連接的狀態。

f.初始化序號。

g.發送初始SYN。

5.PRU_CONNECT2請求。來自於socketpair系統調用,對TCP協議無效。

6.close系統調用會發送PRU_DISCONNECT請求。如果連接已經建立,應調用tcp_disconnect,發送FIN,執行正常的TCP

關閉操作。

7.與accept系統調用有關的工作全部由插口層和協議層完成。PRU_ACCEPT請求只簡單地嚮應用進程返回對端的IP地址

和端口號。

8.PRU_SHUTDOWN請求。應用進程調用shutdown,禁止更多的輸出時,soshutdown會發送PRU_SHUTDOWN請求。

調用socantsendmore置位插口標誌,禁止繼續發送報文段,接着調用tcp_usrclosed,設定正確的連接狀態。

9.PRU_RCVD請求。應用進程從插口的接收緩存中讀取數據後,soreceive會發送這個請求。此時接收緩存已擴大,也許

會有足夠的空間,讓TCP發送更大的窗口通告。tcp_output會決定是否需要發送窗口更新報文段。

10.PRU_SEND請求。調用sbappend,向插口的發送緩存中添加數據,並調用tcp_output發送新報文段(如果條件允許)。

11.PRU_ABORT請求。如果插口是監聽插口,並且存在等待建立的連接,例如已發送初始SYN或已完成三次握手過程,但

還未被服務器accept的連接,調用soclose會導致發送PRU_ABORT請求。如果連接已同步,tcp_drop將發送RST。

12.PRU_SENSE請求。fastat系統調用會生成PRU_SENSE請求。TCP返回發送緩存的大小,保存在stat結構的成員變量中。

13.PRU_RCVOOB請求。當應用進程設置MSG_OOB標誌,試圖讀取帶外數據時,soreceive會發送這一請求。大概流程如下:

a.判斷能否讀取帶外數據。

b.判斷是否有帶外數據到達。

c.返回帶外數據字節。

d.更新標誌。

e.確認發送緩存中有足夠空間並添加新數據。

f.計算緊急指針。

g.強制TCP輸出。

14.PRU_SOCKADDR請求。getsockname系統調用會發送該請求,調用in_setsockaddr函數。

15.PRU_PEERADDR請求。getpeername系統調用會發送該請求,調用in_setpeeraddr函數。調用in_setsockaddr和

in_setpeeraddr函數,從PCB中獲取需要信息,存儲在addr參數中。

16.執行tcp_slowtimo會發送PRU_SLOWTIMO函數。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章