本節我們關注稱為「高階i/o」的各個函式和技術。
首先是在i/o操作上設定超時。在涉及套接字的i/o操作上設定超時的方法有以下3種;
1. 呼叫alarm函式,在定時時間超時產生sigalrm訊號,打斷i/o操作。
首先我們給出要使用的signal1函式的實現,這個函式不是系統呼叫signal的包裹函式,而是我們自己實現的signal1函式的包裹函式。因為linux系統上很多系統呼叫都是自重啟的,在被中斷打斷後會繼續執行,不會返回eintr錯誤。我們想要改變這種行為,因此實現了signal1函式,**如下:
typedef void sigfunc(int); /* for signal handlers */
sigfunc *signal1(int signo, sigfunc *func)
else
if (sigaction(signo, &act, &oact) < 0)
return sig_err;
return oact.sa_handler;
}sigfunc *signal1(int signo, sigfunc *func)
接下來我們實現帶超時的connect函式,**如下:
static void connect_alarm(int signo);
int connect_timeo(int sockfd, const sa *saptr, socklen_t salen, int nsec)
/*關閉報警時鐘*/
alarm(0);
/*恢復之前的訊號處理函式*/
signal1(sigalrm, sigfunc);
return n;
}static void connect_alarm(int signo)
不使用so_rcvtimeo套接字選項是因為connect函式不支援這個選項。
2. 使用select函式設定超時,阻塞在select呼叫上,而不是直接阻塞在read或write呼叫上。
/*使用select為讀描述符fd設定超時*/
int readable_timeo(int fd, int sec)
int readable_timeo(int fd, int sec)
/*為recvfrom函式設定超時的dg_cli函式*/
void dg_cli(file *fp, int sockfd, const sa *pservaddr, socklen_t servlen)
else
}}
3. 使用so_rcvtimeo和so_sndtimeo套接字選項。
/*使用so_rcvtimeo套接字選項為recvfrom設定超時*/
void dg_cli(file *fp, int sockfd, const sa *pservaddr, socklen_t servlen)
else
err_sys("recvfrom error");
} recvline[n] = 0;
fputs(recvline, stdout);
}}
下面給出一些相對read和write函式更高階的i/o函式的api。
#include struct iovec ;
/*分散讀函式*/
ssize_t readv(int fd, const struct iovec *iov, int iovcnt);
/*集中寫函式*/
ssize_t writev(int fd, const struct iovec *iov, int iovcnt);
#include #include /*類似read和write函式,可指定標誌*/
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
struct msghdr ;
/*最通用的i/o函式*/
ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
這裡必須要提到recvmsg和sendmsg函式,它是最通用的i/o函式,支援上述i/o函式的所有功能。另外它還可以用來傳送和接收輔助資料,後面我們就要使用這兩個函式來實現程序間傳遞描述符的技術。 《UNIX網路程式設計 卷1》 筆記 UNIX域協議
unix域協議並不是乙個實際的協議族,而是在單個主機上客戶程序和伺服器程序之間通訊的一種方法。unix域使用的套接字結構如下 struct sockaddr un int main int argc,char argv 執行結果如下 可以看到繫結的路徑名 tmp 123 現在是乙個套接字檔案。uni...
《UNIX網路程式設計 卷2》 筆記 管道
管道是最初的unix ipc形式,它的侷限性在於沒有名字,只能在有親緣關係的程序間使用。後來,fifo出現了,fifo也稱為有名管道。管道和fifo都使用read和write函式訪問。include int pipe int fd 2 管道由pipe函式建立,返回兩個描述符 fd 0 用來讀,fd ...
《UNIX網路程式設計 卷1》 筆記 描述符傳遞技術
linux提供了一種從乙個程序向另乙個程序傳遞任意開啟的描述符的技術,這兩個程序可以無親緣關係。這種技術要求首先在這兩個程序之間建立乙個unix域套接字,然後使用sendmsg跨套接字傳送乙個特殊的訊息,這個訊息由核心來處理,會把開啟的描述符傳遞到接收程序。先來看看要使用的資料結構和函式。struc...