狠狠色丁香婷婷综合尤物/久久精品综合一区二区三区/中国有色金属学报/国产日韩欧美在线观看 - 国产一区二区三区四区五区tv

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發文檔 其他文檔  
 
網站管理員

socket close()和shutdown()區別

admin
2017年4月14日 14:28 本文熱度 7568

shutdown() doesn''t actually close the file descriptor—it just changes its usability. To free a socket descriptor, you need to use close().

  • shutdown是一種優雅地單方向或者雙方向關閉socket的方法。 而close則立即雙方向強制關閉socket并釋放相關資源。

  • 如果有多個進程共享一個socket,shutdown影響所有進程,而close只影響本進程。

以下均基于單進程socket。

服務端調用shutdown()

  • server調用shutdown(),此時任何后續的send,recv都是無效的(根據關閉發送還是關閉接收有所不同)。shutdown本身并不影響底層,也就是說,此前發出的異步send/recv不會返回。其次,在所有已發送的包被client確認后,server會發送FIN包給client,開始TCP四次揮手過程。

  • 注意不管是關閉發送還是關閉接收,server端均向client端發送FIN報文。client 端收到FIN報文后,并不知道server端以何種方式shutdown,甚至不知道server端是shutdown還是close。

  • client端收到FIN報文之后,詳見下文敘述......

服務端調用close()

通過參數設置不同,調用close會出現如下A,B兩種情況:

A. 向客戶端發送一個RST報文,丟棄本地緩沖區的未讀數據,關閉socket并釋放相關資源,此種方式為強制關閉。(l_onoff為非0,l_linger為0,)

B. 向客戶端發送一個FIN報文,收到client端FIN ACK后,進入了FIN_WAIT_2階段,可參考TCP四次揮手過程,此種方式為優雅關閉。如果在l_linger的時間內仍未完成四次揮手,則強制關閉。( l_onoff 為非0,l_linger為非0)

FIN與RST

  • 若server端發送FIN報文后沒有收到client端的FIN ACK,會兩次重傳FIN報文,若一直收不到client端的FIN ACK,則會給client端發送RST信號,關閉socket并釋放資源。(不同系統實現可能會不同)

  • client收到FIN信號后,再調用read函數會返回0。因為FIN的接收,表明client端以后再無數據可以接收,對方發來FIN,表明對方不在發送數據了。

(注意所有FIN及ACK報文均由操作系統自動完成發送接收)

  • client收到FIN后,會發送應答ack報文,表明收到server的FIN報文,server收到ack報文之后,就進入了FIN_WAIT_2階段。

  • 根據tcp協議,向一個 FIN_WAIT2 狀態的 TCP寫入數據是沒有問題的,所以此時client可以調用write函數,寫入到發送緩沖區,并由tcp連接,發送到server的接收緩沖區。由于server端已經關閉了socket,所以此時的server接收緩沖區的內容都被拋棄,同時server端返回RST給客戶端。

  • client端如何知道已經接收到RST報文?

server發送RST報文后,并不等待從client端接收任何ack響應,直接關閉socket。而client端收到RST報文后,也不會產生任何響應。client端收到RST報文后,程序行為如下:

  1. 阻塞模型下,內核無法主動通知應用層出錯,只有應用層主動調用read()或者write()這樣的IO系統調用時,內核才會利用出錯來通知應用層對端已經發送RST報文。
  2. 非阻塞模型下,select或者epoll會返回sockfd可讀,應用層對其進行讀取時,read()會報RST錯誤。

通過read write函數出錯返回后,獲取errno來確定對端是否發送RST信號。

  • client收到RST報文后應如何處理?

client端收到RST信號后,如果調用read函數讀取,則會返回RST錯誤。在已經產生RST錯誤的情況下,繼續調用write,則會發生epipe錯誤。此時內核將向客戶進程發送 SIGPIPE 信號,該信號默認會使進程終止,通常程序會異常退出(未處理SIGPIPE信號的情況下)。

在收到server發送RST報文的情況下,client端的任何read write都是毫無意義的。


該文章在 2017/4/14 14:28:33 編輯過

全部評論1

admin
2017年4月14日 14:30
socket關閉有2個close,shutdown 他們之間的區別: close-----關閉本進程的socket id,但鏈接還是開著的,用這個socket id的其它進程還能用這個鏈接,能讀或寫這個socket id shutdown--則破壞了socket 鏈接,讀的時候可能偵探到EOF結束符,寫的時候可能會收到一個SIGPIPE信號,這個信號可能直到 socket buffer被填充了才收到,shutdown還有一個關閉方式的參數,0 不能再讀,1不能再寫,2 讀寫都不能。 =============================================================================================================== socket 多進程中的shutdown, close使用 當所有的數據操作結束以后,你可以調用close()函數來釋放該socket,從而停止在該socket上的任何數據操作: close(sockfd); 你也可以調用shutdown()函數來關閉該socket。該函數允許你只停止在某個方向上的數據傳輸,而一個方向上的數據傳輸繼 續進行。如你可以關閉某socket的寫操作而允許繼續在該socket上接受數據,直至讀入所有數據。 int shutdown(int sockfd,int how); Sockfd是需要關閉的socket的描述符。參數 how允許為shutdown操作選擇以下幾種方式: SHUT_RD:關閉連接的讀端。也就是該套接字不再接受數據,任何當前在套接字接受緩沖區的數據將被丟棄。進程將不能對該 套接字發出任何讀操作。對TCP套接字該調用之后接受到的任何數據將被確認然后無聲的丟棄掉。 SHUT_WR:關閉連接的寫端,進程不能在對此套接字發出寫操作 SHUT_RDWR:相當于調用shutdown兩次:首先是以SHUT_RD,然后以SHUT_WR 使用close中止一個連接,但它只是減少描述符的參考數,并不直接關閉連接,只有當描述符的參考數為0時才關閉連接。 shutdown可直接關閉描述符,不考慮描述符的參考數,可選擇中止一個方向的連接。 注意: 1>. 如果有多個進程共享一個套接字,close每被調用一次,計數減1,直到計數為0時,也就是所用進程都調用了close,套 接字將被釋放。 2>. 在多進程中如果一個進程中shutdown(sfd, SHUT_RDWR)后其它的進程將無法進行通信. 如果一個進程close(sfd)將不會 影響到其它進程. 得自己理解引用計數的用法了. 有Kernel編程知識的更好理解了. 以上為轉載文章,后面個人的理解一般在開發過程中,應該是先close(),如果close()失敗才再去調用shutdown()操作,如果shutdown()再失敗,一般這個情況的時候就不是一般的錯誤發生了,對于這種錯誤就涉及到操作系統內核級的錯誤了,所以應用程序開發到這一級就足以。 要注意的是,雖然shutdown()提供了讀寫分別關閉的操作,但是它是影響到所有的進程的,所以需要注意。

該評論在 2017/4/14 14:30:28 編輯過
關鍵字查詢
相關文章
正在查詢...
點晴ERP是一款針對中小制造業的專業生產管理軟件系統,系統成熟度和易用性得到了國內大量中小企業的青睞。
點晴PMS碼頭管理系統主要針對港口碼頭集裝箱與散貨日常運作、調度、堆場、車隊、財務費用、相關報表等業務管理,結合碼頭的業務特點,圍繞調度、堆場作業而開發的。集技術的先進性、管理的有效性于一體,是物流碼頭及其他港口類企業的高效ERP管理信息系統。
點晴WMS倉儲管理系統提供了貨物產品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質期管理,貨位管理,庫位管理,生產管理,WMS管理系統,標簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務都免費,不限功能、不限時間、不限用戶的免費OA協同辦公管理系統。
Copyright 2010-2025 ClickSun All Rights Reserved