套接字的預設狀態是阻塞的。當發出乙個不能立即完成的套接字呼叫時,其程序將被投入到睡眠,等待相應操作完成。可能阻塞的套接字呼叫可分為以下四類:
(1)輸入操作,包括read、readv、recv、recvfrom和recvmsg等5個函式
對於非阻塞的套接字,如果輸入操作不能被滿足,相應的呼叫立即返回乙個ewouldblock錯誤
(2)輸出操作,包括write、writev、send、sendto和sendmsg共5個函式核心從應用程序的緩衝區複製資料到套接字的傳送緩衝區
對於乙個非阻塞的套接字,如果其傳送緩衝區沒有空間,輸出函式呼叫將立即返回乙個ewouldblock.如果其緩衝區中有一些空間,返回值將是核心能夠複製到該緩衝區中的位元組數
(3)接受外來連線,即accept函式。如果對乙個阻塞的套接字呼叫accept函式,並且尚無新連線到達,呼叫程序將被投入到睡眠
如果對乙個非阻塞的套接字呼叫accept函式,並且尚無新連線到達,accept呼叫將立即返回乙個ewouldblock錯誤
(4)發起外出連線,即用於tcp的connect函式。connect函式一直等到收到對於自己syn的ack才會返回,意味著每個connect都會阻塞其呼叫程序至少乙個伺服器的rtt時間
如果對乙個非阻塞的套接字呼叫connect,並且連線不能立即建立,那麼連線的建立能夠照樣發起(送出三路握手的第乙個分組),不過會返回乙個einprogress錯誤。但是如果伺服器與客戶處於同乙個主機的情況下,連線一般可以立即建立,也需要預備connect立即成功返回的情況
當在乙個非阻塞的套接字上呼叫connect時,connect將立即返回乙個einprogress錯誤,不過已經發起三路握手繼續進行。我們可以用select檢測這個連線建立成功或失敗的條件。非阻塞的connect有三個用途
(1)我們可以把三路握手疊加在其他處理上。在建立連線的這段時間中,我們可以執行其他操作
(2)我們可以同時建立多個連線
(3)我們可乙個給select乙個時間限制,使得我們縮短connect的超時時間
關於select和connect:
當連線建立成功時,描述符變為可寫
當連線遇到錯誤時,描述符變為既可以寫又可以讀
下面我們發起乙個非阻塞的connect:
1: #include"unp.h"
2: int connect_nonb(int sockfd,const sa*saptr,socklen_t salen,int nsec)
3:
25: ...................
26: ...................//判斷是否sockfd既可以讀又可以寫(出現錯誤)
27: }
假設connect被訊號中斷,如果不能由核心重啟,那麼它將返回eintr。我們不能再次呼叫connect等待未完成的連線繼續完成。這樣做導致返回eaddrinuse
我們只能呼叫select等待套接字變為可寫或者出錯
考慮如下情況:
·客戶建立連線後終止它
·select向伺服器返回可讀條件,不過伺服器等待一小段時間才呼叫accept
·在伺服器從select返回到呼叫accept期間,伺服器tcp收到來自客戶的rst
·這個已完成連線被伺服器去除出已完成連線佇列,隊中沒有其他已完成的連線
·伺服器呼叫accept,阻塞
為了避免上述情況,我們採用以下方法:
(1)當select獲悉某個監聽套接字上何時有已完成連線準備好時,總是把這個監聽套接字設定為非阻塞
(2)在後續呼叫accept時忽略以下錯誤:ewouldblock、econnaborted、eintr
UNP UNIX網路程式設計 第十六章 非阻塞式I O
套接字預設狀態是阻塞的。也就是說當發出乙個不能立即完成的套接字呼叫時,程序將被投入睡眠,等待相應操作的完成 一般分為四類 1.輸入操作 包括read readv recv recvfrom recvmsg這5個函式。當套接字緩衝區沒資料可讀時,程序將被投入睡眠狀態,直到有資料可達。2.輸出操作 包括...
linux網路程式設計中阻塞和非阻塞socket的區別
阻塞socket和非阻塞socket 讀操作 對於阻塞的socket,當socket的接收緩衝區中沒有資料時,read呼叫會一直阻塞住,直到有資料到來才返 回。當socket緩衝區中的資料量小於期望讀取的資料量時,返回實際讀取的位元組數。當sockt的接收緩衝 區中的資料大於期望讀取的位元組數時,讀...
linux網路程式設計中阻塞和非阻塞socket的區別
原文 阻塞socket和非阻塞socket 讀操作 對於阻塞的socket,當socket的接收緩衝區中沒有資料時,read呼叫會一直阻塞住,直到有資料到來才返 回。當socket緩衝區中的資料量小於期望讀取的資料量時,返回實際讀取的位元組數。當sockt的接收緩衝 區中的資料大於期望讀取的位元組數...