1. 生成socket時設置
socket函數建立socket默認是阻塞的,也能夠增長選項將socket設置爲非阻塞的:微信
int s = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP);
socket
2. 使用fcntl設置
將socket設置爲非阻塞的函數
if ((nFlags = fcntl (nSock, F_GETFL, 0)) < 0) return 0;nFlags = nFlags | O_NONBLOCK;if (fcntl (nSock, F_SETFL, nFlags) < 0) return 0;
flex
spa
.net
code
orm
將socket設置爲阻塞的blog
if ((nFlags = fcntl (nSock, F_GETFL, 0)) < 0) return 0;nFlags = nFlags & (~O_NONBLOCK);if (fcntl (nSock, F_SETFL, nFlags) < 0) return 0;
rem
3. 非阻塞和阻塞在收發數據時有什麼區別
3.1 發送時的區別
3.1.1 TCP發送(即send函數)
send函數在阻塞模式下,會等待全部數據都被拷貝到發送緩衝區纔會返回,也就是說,阻塞模式下,send函數返回值一定是參數中發送長度的大小;
send函數在非阻塞模式下,會當即返回,可是會盡量的多拷貝數據到緩衝區,但不保證所有拷貝後返回,所以非阻塞模式下,send函數返回值可能比參數中發送長度小,而若是緩衝區滿了的話,就會當即返回;
3.1.2 UDP發送(即sendto函數)
即便在阻塞模式下,sendto也不會阻塞,由於UDP並無真正的發送緩衝區,它所作的只是將應用緩衝區數據拷貝給下層協議棧,加上UDP頭、IP頭等,實際是不存在阻塞的,非阻塞模式也同樣。
3.2 接收時的區別
3.2.1 TCP接收(即recv函數)
在阻塞模式下, recv將會阻塞,直到緩衝區裏有至少一個字節才返回,當沒有數據到來時,recv會一直阻塞或者直到超時,不會返回;
在非阻塞模式下, recv不會阻塞,若是緩衝區裏有任何一個字節,都會當即返回, 而若是沒有數據,則返回錯誤WSAEWOULDBLOCK;
3.2.2 UDP接收(即recvfrom函數)
在阻塞模式下,recvfrom將會阻塞,直到緩衝區裏有一個完整UDP數據包纔會返回;
在非阻塞模式下,recvfrom函數會當即返回, 若是緩衝區有一個完整數據包,就會返回數據報大小,若是沒有數據,也是返回錯誤WSAEWOULDBLOCK;
本文分享自微信公衆號 - cpp加油站(xy13640954449)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。