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

2021-09-07 11:23:24 字數 2943 閱讀 4083

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

在涉及套接字的i/o操作上設定超時的方法有三種:

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

2:在select中堵塞等待i/o(select有內建的時間限制),依次取代直接堵塞在read或write呼叫上。(linux2.6以後的核心也能夠使用epoll的epoll_wait)。

3:使用較新的so_rcvtimeo和so_sndtimeo套接字選項。這種方法的問題在於並不是全部的實現都支援這兩個套接字選項。

上述這三個技術都適用於輸入和輸出操作(read、write。及其變體recv/send, readv/writev, recvfrom, sendto)。

只是我們也期待能夠用於connect的技術,由於tcp內建的connect超時相當長(典型值為75秒),而我們在寫server程式的時候,也不會希望乙個連線的建立須要花費這麼長時間。

select可用來在connect上設定超時的先決條件是對應的套接字是非堵塞的。而那兩個套接字選項對connect並不適用。同一時候也應當指出,前兩個技術適用於不論什麼描寫敘述符。而第三個技術只適用於套接字描寫敘述符。

>>>>使用select對connect設定超時:

#include #include #include #include #include #include #include #include #include #include #include #include #define port 9900

#define maxdatasize 5000

int main(int argc, char **ar**)

if((he = gethostbyname(ar**[1])) == null)

if((sockfd = socket(af_inet, sock_stream, 0)) == -1)

bzero(&servaddr, sizeof(servaddr));

servaddr.sin_family = af_inet;

servaddr.sin_port = htons(port);

servaddr.sin_addr = *((struct in_addr *)he->h_addr);

fcntl(sockfd, f_setfl, o_nonblock);

timeval timeout = ;

if(connect(sockfd, (sa*)&servaddr, sizeof(struct sockaddr)) == -1)

}fd_set readset;

fd_zero(&readset);

fd_zero(&writeset);

fd_set(sockfd, &writeset);

int ret = select(sockfd+1, &readset, &writeset, null, &timeout);

printf("%d", ret);

}

>>>>使用sigalrm為connect設定超時:

#include static void connect_alarm(int);

intconnect_timeo(int sockfd, const sa* saptr, socklen_t salen, int nsec)

alarm(0); /* turn off the alarm */

signal(sigalrm, sigfunc); /* restore previous signal handler */

return (n);

}static void

connect_alarm(int signo)

>>>>使用sigalrm為recvfrom設定超時:

#include static void sig_alarm(int);

void

dig_cli(file* fp, int sockfd, const sa* pservaddr, socklen_t servlen)

else

}}static void

sig_alarm(int signo)

>>>>使用select為recvfrom設定超時:

#include int

readable_timeo(int fd, int sec)

所以上面dig_cli函式結合readable_timeo函式設定超時的程式就可變為:(堵塞在select上)

#include void

dig_cli(file* fp, int sockfd, const sa* pservaddr, socklen_t servlen)

else

}}

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

#include void

dig_cli(file* fp, int sockfd, const sa* pservaddr, socklen_t servlen)

else

err_sys("recvfrom error");

}recvline[n] = 0; /* null terminate */

fputs(recvline, stdout);

}}

UNIX網路程式設計 基礎套接字程式設計

就像 unix網路程式設計 裡面說的,我們可以將tcp的連線看成乙個 系統,那麼我們的套接字位址結構,就是我們的 裡面號碼,和其他能確定我們身份資訊的集合。其中ipv4的,我們已經很熟悉,還有另外的,在ipv6如果系統支援長度字段,那麼sin6 len常值必須定義,在使用這一結構時我們必須分清到底,...

UNIX網路程式設計 套接字程式設計介紹

列印當前機器是小頭派還是大頭派型別 注意,如果沒有加這兩個標頭檔案 include include 編譯時候會報 警告 隱式宣告與內建函式 printf 不相容 這個錯誤 編譯 gcc o byteorder byteorder.c include include int main int argc...

UNIX網路程式設計 原始套接字SOCK RAW

實際上,我們常用的網路程式設計都是在應用層的報文的收發操作,也就是大多數程式設計師接觸到的流式套接字 sock stream 和資料報式套接字 sock dgram 而這些資料報都是由系統提供的協議棧實現,使用者只需要填充應用層報文即可,由系統完成底層報文頭的填充並傳送。然而在某些情況下需要執行更底...