网络编程中的超时检测
我們在網絡編程中常見的一種做法是:創建好套接字后以阻塞的方式讀寫,如果沒有數據可讀的話,程序會一直等待。事實上,網絡狀況一直不斷變化,很有可能在通訊過程中出現網絡連接斷開。我們在程序中有必要對這種情況進行檢測,從而及時做出響應。下面介紹幾種常用的超時檢測方法(假設我們要求通過套接字等待數據的最大時間為8秒):
一、 設置套接字接收超時
setsockopt可以設置套接字的屬性,其中包括接收超時時間。參考代碼如下
STruct?TImeval tv; // 描述時間的結構體變量
……
tv.tv_sec = 8;
tv.tv_usec = 0;
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
……
二、 多路IO復用select
select 函數通常被用來實現多路IO復用,同樣可以利用它來實現超時處理。參考代碼如下:
struct timeval tv; // 描述時間的結構體變量
fdset rdfds; // 定義讀描述符集合
……
tv.tv_sec = 8;
tv.tv_usec = 0;
FD_ZERO(&rdfds);
FD_SET(sockfd, &rdfds);
if (select(sockfd+1, &rdfds,?NULL, NULL, &tv) == 0)
{
超時處理
}
……
三、 設置定時器
這種方法的原理是在從套接字接收數據之前先設置8秒鐘的定時器。如果8秒鐘內沒有數據到來,內核產生的SIGALRM信號會中斷當前的讀操作。我們知道設置信號捕捉函數可以用signal函數或是sigactiON函數。但這里只能使用sigaction函數,因為signal設置的信號處理函數執行完后會重新執行被中斷的操作。參考代碼如下:
void handler(int signo) // 自定義SIGALRM信號處理函數
{
return;
}
struct sigaction act; // 描述信號行為的變量
……
sigaction(SIGALRM, NULL, &act); // 獲取SIGALRM信號的屬性
act.sa_handler = handler; // 設置SIGALRM信號的處理函數
act.sa_flags &= ~SA_RESTART; // 關閉重啟被中斷操作的選項
sigaction(SIGALRM, &act, NULL); // 設置SIGALRM信號的屬性
alarm(8); // 設置8秒鐘的定時器
……
雖然我們是以套接字的讀操作為例,實際上在很多類似的情況中,大家都可以酌情采取上面介紹的方法。巧妙的運用所學知識會讓你的程序更加靈活和人性化。
總結
以上是生活随笔為你收集整理的网络编程中的超时检测的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java中发送结构体
- 下一篇: arm 驱动基础:查询方式的按键驱动程序