socket阻塞與非阻塞模式區別

首先什麼是阻塞,什麼是非阻塞呢?

通俗的說,阻塞就是事情沒幹完,但是現在暫時無法幹,還得在那兒等着

非阻塞就是事情沒幹完,現在暫時沒法幹,我先離開一會兒,待會兒回來再幹。


拿recv和send函數來說,send發送一定byte的數據,其實是把數據拷貝到TCP/IP協議棧中的輸出mbuf(http://blog.csdn.net/shinichr/article/details/23044999)中,它執行成功不是指已經成功的把數據發給了對方。

這時候如果輸出mbuf沒有足夠的空間保存數據呢?對於阻塞模式下,send將不返回知道mbuf有足夠的空間來保存數據。而非阻塞模式會立即返回一個緩存區已滿的提醒,這時候需要我們去處理。

對於recv來說,道理和send類似的。


那麼socket的阻塞函數有哪些呢? 

accept,connect,recv(recvfrom),send(sendto),closesocket,select(poll或epoll)
accept在阻塞模式下,沒有新連接時,線程會進入睡眠狀態;非阻塞模式下,沒有新連接時,立即返回WOULDBLOCK錯誤

connect在阻塞模式下,僅TCP連接建立成功或出錯時才返回,分幾種具體的情況,這裏不再敘述;非阻塞模式下,該函數會立即

返回INPROCESS錯誤(可以用select檢測該連接是否建立成功)   

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


設置socket阻塞模式方法也很簡單:

linux:
          fcntl(socket, F_SETFL, flags | O_NONBLOCK);
          read/recv函數的最後一個參數也可以設置阻塞或非阻塞方式


windows:
          ioctlsocket,WSAAsyncselect()和WSAEventselect()
    read/recv函數的最後一個參數也可以設置阻塞或非阻塞方式


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章