給套接字設定超時檢測

2021-06-19 01:58:59 字數 2999 閱讀 7537

在涉及套接字i/o操作上設定超時的方法有以下3種。

呼叫alarm, 它在指定超時期滿時產生sigalrm訊號。這個方法涉及訊號處理,而訊號處理在不同的實現上存在差異,而且可能干擾程序中現有的alarm呼叫。

在select中阻塞等待i/o(select有內建的時間限制),以此代替直接阻塞在read或write呼叫上。

使用較新的so_rcvtimeo和so_sndtimeo套接字選項。這個方法的問題在於並非所有實現都支援這兩個套接字選項。

select可用在connect上設定超時的先決條件是相應套接字處於非阻塞模式,而那兩個套接字選項對connect並不適用。前兩個技術適用於任何描述符,而第三個技術僅使用於套接字描述符。

使用sigalrm為connect設定超時

先給出原始碼:

static

void

connect_alarm(

int);

intconnect_timeo(

intsockfd, 

const

sa *saptr, socklen_t salen, 

intnsec)

alarm(0);

signal(sigalrm, sigfunc);

return

(n); }

static

void

connect_alarm(

intsigno)

本程序的報警時鐘設定成由呼叫者指定的秒數。如果當前已經給本程序設定過報警時鐘,那麼alarm的返回值是這個報警時鐘的當前剩餘秒數,且返回乙個警告訊息,因為我們推翻了先前設定的報警時鐘,否則alarm的返回值為0。

呼叫connect,如果本呼叫被中斷(即返回eintr錯誤),那就把errno的值改設為etimeout,同時關閉套接字,以防三路握手繼續進行。

給alarm函式指定引數0,關閉本程序的報警時鐘,同時恢復原來的訊號處理函式(如果有的話)。

使用sigalrm為recvfrom設定超時

static

void

sig_alrm(

int);

void

dg_cli(file *fp, 

intsockfd, 

const

sa *pservaddr, socklen_t servlen)

else

} }

static

void

sig_alrm(

intsigno)

為sigalrm建立乙個訊號處理函式,並在每次呼叫recvfrom前呼叫alarm設定乙個5秒鐘的超時。如果recvfrom被我們的訊號處理函式中斷了,那就輸出乙個資訊並繼續執行。如果讀到一行來自伺服器的文字,那就關掉報警時鐘並輸出伺服器的應答。

使用select為recvfrom設定超時

下面這個readable_timeo函式等待乙個描述符最多在指定的秒數內變為可讀。

intreadable_timeo(

intfd, 

intsec)

intreadable_timeo(

intfd, 

intsec)

select等待該描述符變為可讀,或者超時。本函式的返回值就是select的返回值;

出錯為-1,超時發生時為0,否則返回的正值給出已就緒描述符的數目。

下面是dg_cli函式的原型:

void

dg_cli(file *fp, 

intsockfd, 

const

sa *pservaddr, socklen_t servlen)

else} }

該函式呼叫readable_timeo函式,當返回值大於0時才呼叫recvfrom,確保recvfrom不會阻塞。

使用so_rcvtimeo套接字選項為recvfrom設定超時

本選項一旦設定到某個描述符(包括指定超時值),其超時設定將應用於該描述符的所有讀操作。本方法的優勢就體現在一次性設定選項上,而前兩個方法總是要求我們在欲設定時間限制的每個操作發生之前做些工作。本套接字選項僅僅應用於讀操作,類似的so_sndtimeo選項則僅僅應用於寫操作,兩者都不能用於為connect設定超時。

下面是使用so_rcvtimeo套接字選項的另乙個版本的dg_cli函式。

void

dg_cli(file *fp, 

intsockfd, 

const

sa *pservaddr, socklen_t servlen)

else

err_sys(

"recvfrom error");

} recvline[n] = 0;

fputs(recvline, stdout);} }

如果i/o操作超時,其函式(這裡是recvfrom)將返回乙個ewouldblock錯誤。

-

傳送心跳包來檢測

------解決方案--------------------

你理解的socket模型不夠正確

socket設計的基礎是假定不知道當前狀態,事實上也不可能立即(immediately)隨時知道是否連線

所以設計者考慮在read/write時丟擲異常來反映給client,除非主動斷開連線會有握手

那你要根據這個概念去寫,

就是在write時catch斷開的異常,其次如果需要知道大概的連線狀態,則是定時由client向server傳送心跳包來維護當前狀態。

may it helps.

------解決方案--------------------

用另乙個執行緒定時向伺服器傳送資料,如果物理斷開就會出現異常,

------解決方案--------------------

只有在read/receive時才會觸發檢查物理鏈路,否則無視物理鏈路

所以通過傳送心跳包定時檢測物理鏈路的連通性

給套接字設定超時檢測

在涉及套接字i o操作上設定超時的方法有以下3種。呼叫alarm,它在指定超時期滿時產生sigalrm訊號。這個方法涉及訊號處理,而訊號處理在不同的實現上存在差異,而且可能干擾程序中現有的alarm呼叫。在select中阻塞等待i o select有內建的時間限制 以此代替直接阻塞在read或wri...

套接字超時

在涉及套接字的i o操作上設定超時的方法有一下3種 1 呼叫alarm,它在指定超時期滿時產生sigalrm訊號,這個方法涉及訊號處理,而訊號處理在不同的實現上存在差異,而且可能干擾程序中現有的alarm呼叫 2 在select中阻塞等待 i o select有內建的時間限制 以此代替直接阻塞在re...

Unix網路程式設計 高階IO套接字設定超時

我們知道。對於乙個套接字的讀寫 read write 操作預設是堵塞的。假設當前套接字還不可讀 寫,那麼這個操作會一直堵塞下去,這樣對於乙個須要高效能的server來說,是不能接受的。所以,我們能夠在進行讀寫操作的時候能夠指定超時值,這樣就讀寫操作就不至於一直堵塞下去。在涉及套接字的i o操作上設定...