linux 設定connect 超時

2022-06-23 06:15:21 字數 2692 閱讀 9375

將乙個socket 設定成阻塞模式和非阻塞模式,使用fcntl方法,即:

設定成非阻塞模式:

先用fcntl的f_getfl獲取flags,用f_setfl設定flags|o_nonblock;        

即:flags = fcntl(sockfd, f_getfl, 0);                        //獲取檔案的flags值。

fcntl(sockfd, f_setfl, flags | o_nonblock);   //設定成非阻塞模式;

同時在接收和傳送資料時,需要使用msg_dontwait標誌

即:在recv,recvfrom和send,sendto資料時,將flag設定為msg_dontwait。

設定成阻塞模式:

先用fcntl的f_getfl獲取flags,用f_setfl設定flags&~o_nonblock;      

即:flags  = fcntl(sockfd,f_getfl,0);                          //獲取檔案的flags值。

fcntl(sockfd,f_setfl,flags&~o_nonblock);    //設定成阻塞模式;            

同時在接收和傳送資料時,需要使用阻塞標誌

即:在recv,recvfrom和send,sendto資料時,將flag設定為0,預設是阻塞。       

在將socket設定成非阻塞模式後,每次的對於sockfd 的操作都是非阻塞的;

非阻塞模式下:

connect   

=0   當返回0時,表示立即建立了socket鏈結,

<0   當返回-1時,需要判斷errno是否是einprogress(表示當前程序正在處理),否則失敗。

select監聽connect是否成功的例子,注意getsockopt驗證,因為三次握手的第三個ack有可能會丟失,但是客戶端認為鏈結已經建立:

int ret = ::connect(_socket_fd, add.addr(), add.length());

if(ret == 0)

else if(ret < 0 && errno == einprogress)          //errno == einprogress表示正在建立鏈結

else if(retval == 0) // 超時

//將檢測到_socket_fd讀事件或寫時間,並不能說明connect成功

if(fd_isset(_socket_fd,&set))

if(error != 0) // 失敗

else}}

else

/*int error = 0;

socklen_t ilen = sizeof(error);

ret = getsockopt(fd,sol_socket,so_error,&error,&ilen);

if(ret < 0)

else if(error != 0 )

else

*/                      

recv 和 recvfrom

=0  當返回值為0時,表示對端已經關閉了這個鏈結,我們應該自己關閉這個鏈結,即close(sockfd)。另外因為非同步操作會用select或epoll做事件觸發,所以:

1、如果使用select,應該使用fd_clr(sockfd,fd_set)將sockfd清除掉,不再監聽。

2、如果使用epoll,系統會自己將sockfd清除掉,不再進行監聽。

>0 當返回值大於0 且 小於sizeof(buffer)時,表示資料肯定讀完。(如果等於sizeof(buffer),可能有資料還沒讀,應該繼續讀,不可能有大於)

<0 當返回值小於0,即等於-1時,分情況判斷:

1、如果   errno   為  eagain  或 ewouldblock                                      

表示暫時無資料可讀,可以繼續讀,或者等待epoll或select的後續通知。(eagain,ewouldblock產生的

原因:可能是多程序讀同乙個sockfd,可能乙個程序讀到資料,其他程序就讀取不到資料(類似驚群效應),當然

單個程序也可能出現這種情況。對於這種錯誤,不需用close(sockfd)。可以等待select或epoll的下一次觸發,

繼續讀。)

2、如果   errno   為  eintr

表示被中斷了,可以繼續讀,或者等待epoll或select後續的通知。

否則,真的是讀取資料失敗。(此時應該close(sockfd))

send和sendto      

返回值是實際傳送的字元數,因為我們知道要傳送的總長度,所以,如果沒有傳送完,我們可以繼續傳送。

<0 當返回值為 -1   時, 我們需要判斷  errno:

1、如果errno為  eagain   或 ewouldblock ,表示當前緩衝區寫滿,可以繼續寫,

或者等待epoll或select的後續通知,一旦有緩衝區,就會觸發寫操作,這個也是經常利用的乙個特性。  

2、如果errno為eintr  ,表示被中斷了,可以繼續寫,或者等待epoll或select的後續通知。

否則真的出錯了,即errno不為eagain或ewouldblock或eintr,此時應該close(sockfd)

>=0 >=0且不等於要求傳送的長度,應該繼續send,如果等於要求傳送的長度,傳送完畢。

connect設定連線超時

庖丁解牛 connect timeout 帶超時的connect 方法中已執行connect fd 檔案描述符 addr 位址結構體指標 wait seconds 等待超時秒數,如果為0表示不檢測超時 成功返回0.失敗返回 1,超時返回 1並且errno etimedout int connect ...

C socket 關於connect超時設定

使用阻塞的socket,可以設定讀寫超時,struct timeval tv timeout tv timeout.tv sec 60 tv timeout.tv usec 0 if setsockopt sockfd,sol socket,so sndtimeo,void tv timeout,s...

accept與connect的超時設定

connect超時 我們都知道,connect對應與三次握手中的第一次傳送syn,而對待伺服器的ack,如果伺服器沒有啟動伺服器,有些機器會立刻返回乙個rst表示伺服器拒絕,從而connect失敗,但又些伺服器為了防止攻擊,什麼也不傳送,直至客戶端connect超時,而這一時間又75s,對於客戶端來...