Socket的非阻塞模式

2021-10-04 03:47:15 字數 3096 閱讀 6127

阻塞模式:如果伺服器沒有回應則一直等待,若等待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函式來檢查這個連線是否建立成功

當連線成功建立時,描述字變成可寫

當連線建立出錯時,描述字變成即可讀又可寫,getsockopt()函式的errno == 0表示只可寫

因此可以通過select判斷描述字是否可寫,再呼叫getsockopt()判斷描述字是否只可寫來判斷是否連線成功

非阻塞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是否完成,該函式所在的執行緒會繼續執行。在阻塞模式的套接字上,呼叫任何...