天天看點

《UNIX網絡程式設計 卷1:套接字聯網API(第3版)》——8.12 dg_cli函數(修訂版)

本節書摘來自異步社群《unix網絡程式設計 卷1:套接字聯網api(第3版)》一書中的第8章,第8.12節,作者:【美】w. richard stevens , bill fenner , andrew m. rudoff著,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視

現在我們回到圖8-8中的dg_cli函數,把它重寫成調用connect。圖8-17所示為新的函數。

《UNIX網絡程式設計 卷1:套接字聯網API(第3版)》——8.12 dg_cli函數(修訂版)

所做的修改是調用connect,并以read和write調用代替sendto和recvfrom調用。該函數不檢視傳遞給connect的套接字位址結構的内容,是以它仍然是協定無關的。圖8-7中的客戶程式main函數保持不變。

在主機macosx上運作該程式,并指定主機freebsd4的ip位址(它沒有在端口9877上運作相應的伺服器程式),我們得到如下輸出:

我們首先注意到,當啟動客戶程序時我們并沒有收到這個錯誤。該錯誤隻是在我們發送第一個資料報給伺服器之後才發生。正是發送該資料報引發了來自伺服器主機的icmp錯誤。然而當一個tcp客戶程序調用connect,指定一個不在運作伺服器程序的伺服器主機時,connect将傳回同樣的錯誤,因為調用connect會造成tcp三路握手,而其中第一個分節導緻伺服器tcp返送rst(4.3節)。

圖8-18給出了tcpdump的輸出。

《UNIX網絡程式設計 卷1:套接字聯網API(第3版)》——8.12 dg_cli函數(修訂版)

我們還從圖a-15中看到,該icmp錯誤由核心映射成econnrefused錯誤,對應于由err_sys函數輸出的消息串:“connection refused”(連接配接被拒絕)。

不幸的是,并非所有核心都能像本節的示例那樣把icmp消息返送給已連接配接的udp套接字。一般來說,源自berkeley的核心傳回這種錯誤,而system v核心則不。舉例來說,如果我們在一個solaris 2.4主機上運作同一個客戶程式,并connect到沒有運作伺服器的一個主機上,我們就可以用tcpdump觀察并驗證伺服器主機傳回了icmp端口不可達錯誤,但是客戶的read調用永不傳回。這個缺陷在solaris 2.5中已修複。unixware不傳回這種錯誤,而aix、digital unix、hp-ux和linux都傳回這種錯誤。

繼續閱讀