阻塞模式:如果伺服器沒有回應則一直等待,若等待75秒後仍沒有響應則返回-1
非阻塞模式:無論connect是否成功都立即返回
非阻塞與阻塞工作模式的優缺點
阻塞處理簡單,非阻塞處理複雜
阻塞效率低,非阻塞效率高
阻塞模式,常見的通訊模型為多執行緒模型,服務端accept之後,對每個socket建立乙個執行緒去recv。邏輯上簡單,適用於併發量小(客戶端數目少),連續傳輸大資料量的情況下,比如檔案伺服器。還有就是在客戶端recv伺服器訊息的時候也經常用,因為客戶端就乙個socket,用阻塞模式不影響效率,而且程式設計邏輯上要簡單得多
非阻塞模式,常見的通訊模型為select模型和iocp模型。適用於高併發,資料量小的情況,比如聊天室。客戶端多的情況下,如果採用阻塞模式,需要開很多執行緒,影響效率。另外,客戶端一般不採用非阻塞模式socket在建立的時候預設是阻塞的,將socket設定為非阻塞的有以下幾種方法
1.ioctl 設定已經建立socket的fd
ioctl用於裝置控制
#include
intioctl
(int fd,
unsigned
long request,..
.);
通過下面的語句設定
unsigned
long ul =1;
ioctl
(socketfd, fionbio,
&ul)
;
此方法設定非阻塞通常在呼叫connect之後,否則會報錯「operation now in progress」.
2.fcntl設定已經建立socket的fd
fcntl用於檔案控制
#include
#include
intfcntl
(int fd,
int cmd,..
./* arg */
);
通過下面方式設定:
flags =
fcntl
(sfd, f_getfl)
;flags |
= o_nonblock;
fcntl
(sfd, f_setfl, flags)
;
3.在建立socket的時候設定
int fd =
socket
(af_inet, sock_stream | sock_nonblock,0)
;
4.accept4
int
accept4
(int sockfd,
struct sockaddr *addr,socklen_t *addrlen,
int flags)
;
flags 設定成 sock_nonblock,這種方式是在服務端
非阻塞socket在connect後會立即返回,連線成功返回零,連線正在進行(沒有立即完成)或連線失敗都返回-1並把錯誤**記錄到errno中,連線正在進行時返回錯誤**einprocess,因此當connect函式返回值為-1時需要通過errno的返回**判斷connect函式是否處於正在連線的狀態
如果errno錯誤碼為einprocess,說明tcp通訊的三路握手過程正在進行,這時需要呼叫select函式來檢查這個連線是否建立成功
當連線成功建立時,描述字變成可寫因此可以通過select判斷描述字是否可寫,再呼叫getsockopt()判斷描述字是否只可寫來判斷是否連線成功當連線建立出錯時,描述字變成即可讀又可寫,getsockopt()函式的errno == 0表示只可寫
非阻塞connect()的基本流程:
呼叫connect()連線伺服器
呼叫ioctl函式設定connect為非阻塞
判斷返回值,返回0說明連線成功;返回-1繼續檢查errno是否為einprocess
若連線正在進行,將socket的fd加入到select的可寫集合中去,設定select的超時時間
當fd變為可寫時呼叫getsockopt函式判斷fd是否只可寫(errno==0)
conn_check=
connect
(socketfd,
(struct sockaddr *
)&serv_addr,
sizeof
(serv_addr));
ioctl
(socketfd, fionbio,
&ul)
;//設定socket非阻塞
if(conn_check<0)
//連線沒有立即成功
fd_zero
(&writeset)
;//初始化select可寫集合
fd_set
(socketfd,
&writeset)
;//將socketfd加入到select可寫集合
memset
(&timeout,0,
sizeof
(timeout));
timeout.tv_sec=15;
//設定select超時時間為15秒
timeout.tv_usec=0;
rv=select
(socketfd+1,
null
,&writeset,
null
,&timeout);if
(rv<0)
if(rv==0)
if(rv>0)
if(err==0)
//描述符只可寫,連線成功}}
else
//連線成功
Socket 阻塞模式和非阻塞模式
阻塞i o模型 簡介 程序會 一直阻塞 直到資料拷貝 完成 應用程式呼叫乙個io函式,導致應用程式阻塞,等待資料準備好。如果資料沒有準備好,一直等待 資料準備好了,從核心拷貝到使用者空間,io函式返回成功指示。阻塞i o模型圖 在呼叫recv recvfrom 函式時,發生在核心中等待資料和複製資料...
Socket的阻塞模式和非阻塞模式
阻塞模式 windows套接字在阻塞和非阻塞兩種模式下執行i o操作。在阻塞模式下,在i o操作完成前,執行的操作函式一直等候而不會立即返回,該函式所在的執行緒會阻塞在這裡。相反,在非阻塞模式下,套接字函式會立即返回,而不管i o是否完成,該函式所在的執行緒會繼續執行。在阻塞模式的套接字上,呼叫任何...
Socket的阻塞模式和非阻塞模式
阻塞模式 windows套接字在阻塞和非阻塞兩種模式下執行i o操作。在阻塞模式下,在i o操作完成前,執行的操作函式一直等候而不會立即返回,該函式所在的執行緒會阻塞在這裡。相反,在非阻塞模式下,套接字函式會立即返回,而不管i o是否完成,該函式所在的執行緒會繼續執行。在阻塞模式的套接字上,呼叫任何...