非阻塞socket程式設計

2021-06-23 02:26:43 字數 1375 閱讀 9642

socket程式設計中可能出現阻塞的呼叫有4個:

1. write、send、sendto、sendmsg、sendv等,如果某個程序呼叫乙個阻塞的tcp套接字(預設設定),如果傳送緩衝區沒有空間,呼叫程序將會睡眠,直到有空間為止。 如果tcp套接字是非阻塞的,且沒有空間可寫,則會返回乙個ewouleblock的錯誤。

2.read、recv、recvfrom、recvmsg、recvv等,如果某個程序呼叫乙個阻塞的tcp套接字(預設設定),如果接收緩衝區沒有資料可讀,呼叫程序將會睡眠,直到有資料可讀為止。 如果tcp套接字是非阻塞的,且沒有資料可讀,則會返回乙個ewouleblock的錯誤。

3. accept呼叫,如果乙個阻塞的套接字呼叫accept且沒有新連線到達,則呼叫程序將睡眠。如果乙個非阻塞的套接字呼叫accept且沒有新連線到達,呼叫程序返回ewouleblock。

4. connect 呼叫,connect至少會阻塞其呼叫程序乙個rtt(rtt從微秒到幾秒不等),如果乙個非阻塞的套接字呼叫connect,且不能立即建立連線,則會返回乙個einprocess,正在進行3路握手連線。如果connect非阻塞,如果檢查其成功建立連線是乙個比較麻煩的過程。

對應1、2、3,可以在select觀察到描述符發生變化後再呼叫它們,則可防止阻塞發生。但是對於4只能先設定套接字為非阻塞(通過fnctl)。

處理非阻塞connect的步驟:

第一步:建立socket,返回套介面描述符;

第二步:呼叫fcntl把套介面描述符設定成非阻塞;

第三步:呼叫connect開始建立連線;

第四步:判斷連線是否成功建立;

a:如果connect返回0,表示連線簡稱成功(伺服器可客戶端在同一臺機器上時就有可能發生這種情況);

b:呼叫select來等待連線建立成功完成;

如果select返回0,則表示建立連線超時;我們返回超時錯誤給使用者,同時關閉連線,以防止三路握手操作繼續進行下去;

如果select返回大於0的值,則需要檢查套介面描述符是否可讀或可寫;如果套介面描述符可讀或可寫,則我們可以通過呼叫getsockopt來得到套介面上待處理的錯誤(so_error),        如果連線建立成功,這個錯誤值將是0,如果建立連線時遇到錯誤,則這個值是連線錯誤所對應的errno值(比如:econnrefused,etimedout等).

"讀取套介面上的錯誤"是遇到乙個可移植性問題;如果出現問題,getsockopt源自berkeley的實現是返回0,等待處理的錯誤在變數errno中返回;但是solaris會讓getsockopt返回-1,errno置為待處理的錯誤;我們對這兩種情況都要處理;

plus:socket在接收資料(讀)的時候,可以先用ioctl(sockfd, fionread, &nread); 查詢緩衝區中有多少資料,查詢的位元組數放在nread中。如果為0則可以關閉套接字;

非阻塞socket程式設計

阻塞 阻塞呼叫是指呼叫結果返回之前,當前執行緒會被掛起。該程序被標記為睡眠狀態並被排程出去。函式只有在得到結果之後才會返回。當socket工作在阻塞模式的時候,如果沒有資料的情況下呼叫該函式,則當前執行緒就會被掛起,直到有資料為止。非阻塞 非阻塞和阻塞的概念相對應,指在不能立刻得到結果之前,該函式不...

非阻塞socket程式設計

阻塞 阻塞呼叫是指呼叫結果返回之前,當前執行緒會被掛起。該程序被標記為睡眠狀態並被排程出去。函式只有在得到結果之後才會返回。當socket工作在阻塞模式的時候,如果沒有資料的情況下呼叫該函式,則當前執行緒就會被掛起,直到有資料為止。非阻塞 非阻塞和阻塞的概念相對應,指在不能立刻得到結果之前,該函式不...

socket程式設計 阻塞和非阻塞

阻塞方式下,connect首先傳送syn請求道伺服器,當客戶端收到伺服器返回的syn的確認時,則connect返回.否則的話一直阻塞.非阻塞方式,connect將啟用tcp協議的三次握手,但是connect函式並不等待連線建立好才返回,而是立即返回。返回的錯誤碼為einprogress,表示正在進行...