1. 程式人生 > >阻塞Socket和非阻塞Socket

阻塞Socket和非阻塞Socket

什麼是阻塞socket,什麼是非阻塞socket。對於這個問題,我們要先弄清什麼是阻塞/非阻塞。阻塞與非阻塞是對一個檔案描述符指定的檔案或裝置的兩種工作方式。 阻塞的意思是指,當試圖對該檔案描述符進行讀寫時,如果當時沒有東西可讀或者暫時不可寫,程式就進入等待狀態,直到有東西可讀或者可寫為止。 非阻塞的意思是,當沒有東西可讀或者不可寫時,讀寫函式就馬上返回,而不會等待。


現在來理解什麼是阻塞socket,什麼是非阻塞socket。每個通過socket()函式建立的socket,本質就是一個檔案描述符,所以對該檔案描述符的IO操作方式不同,就有了阻塞socket和非阻塞socket。 那是不是說阻塞socket下的所以socket api函式都是阻塞的呢,如果你還不能正確的回答這個問題,說明上面簡短的說明並沒有讓你真正的明白什麼是阻塞socket和非阻塞socket。這個問題的答案是否定的,為什麼是否定的,因為並不是每個socket的api都會涉及到對檔案描述符的IO操作。

 這裡我列舉了,哪些socket api會阻塞:

accept,connect,recv(recvfrom),send(sendto),closesocket,select(poll或epoll)

1)accept在阻塞模式下,沒有新連線時,執行緒會進入睡眠狀態;非阻塞模式下,沒有新連線時,立即返回WOULDBLOCK錯誤。

2)connect在阻塞模式下,僅TCP連線建立成功或出錯時才返回,分幾種具體的情況,這裡不再敘述;非阻塞模式下,該函式會立即返回INPROCESS錯誤(需用select檢測該連線是否建立成功)

3)recv/recvfrom/send/sendto很好理解,因為這兩類函式讀寫socket檔案描述符的接收/傳送緩衝區。 

4) select/poll/epoll並不是真正意義上的阻塞,它們的阻塞是由於它們最後一個timeout引數決定的,timeout大於0時,它們會一直等待直到超時才退出(相等於阻塞了吧,^_^),而timeout=-1即永遠等待。 

來源:http://blog.csdn.net/pingnanlee/article/details/7770087