高階I O函式

2021-08-20 04:12:54 字數 3296 閱讀 4022

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

1.呼叫alarm,在指定超時期滿時產生sigalrm訊號。

2.在select種阻塞等待i/o,一次代替直接阻塞在read或write呼叫上。

3.使用較新的so_rcvtimeo和so_sndtimeo套接字選項。

以由呼叫者指定的超時上限呼叫connect。第四個引數為等待的秒數。

#include "unp.h"

static void connect_alarm(int);

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

alarm(0); //turn off the alarm

signal(sigalrm,sigfunc);

return (n);

}static void connect_alarm(int signo)

改變dg_cli函式,通過呼叫alarm使得一旦在5秒鐘內收不到任何應答就中斷recvfrom

#include "unp.h"

static void sig_alrm(int);

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

else }}

static void sig_alrm(int signo) //signo為訊號資訊。如sigint等

#include "unp.h"

int readable_timeo(int fd, int sec)

/* 呼叫readable_timeo設定超時的dg_cli函式 */

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

else

}}

本選項一旦設定到某個描述符,其超時設定將應用於該描述符上的所有讀操作。

示例:使用so_rcvtimeo套接字選項的另乙個版本的dg_cli函式

#include "unp.h"

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

else

err_sys("recvfrom error");

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

fputs(recvline,stdout);

}

類似標準的read和write函式,不過需要乙個flags引數

#includessize_t recv(int sockfd, void *buff, size_t nbytes, int flags);

ssize_t send(int sockfd, const void *buff, size_t nbytes, int flags);

flags引數:

允許單個系統呼叫讀入到或寫出自乙個或多個緩衝區。這些操作分別稱為分散讀和集中寫。來自讀操作的輸入資料被分散到多個應用緩衝區中,而來自多個應用緩衝區的輸出資料則被集中提供給單個寫操作。

#includessize_t readv(int filedes, const struct iovec *iov, int iovcnt);

ssize_t writev(int filedes, const struct iovec *iov, int iovcnt);

//若成功則返回讀入或寫出的位元組數

第二個引數是指向某個iovec結構陣列的乙個指標,其中iovec結構在標頭檔案中定義:

struct iovec ;
iovec結構陣列中元素的數目存在限制。

readv和writev這兩個函式可用於任何描述符,不僅限套接字。

這兩個函式是最通用的i/o函式。所有read,readv,recv,recvfrom都可以替換成recvmsg呼叫。各種輸出函式也可以替換成sendmsg呼叫。

#includessize_t recvmsg(int sockfd, struct msghdr *msg, int flags);

ssize_t sendmsg(int sockfd, struct msghdr *msg, int flags);

這兩個函式大部分引數都封裝到乙個msghdr結構中:

struct msghdr
mas_name和msg_namelen這兩個成員用於套接字未連線的場合(如未連線udp套接字);

msg_iov和msg_iovlen這兩個成員指定輸入或輸出緩衝區陣列。

下圖展示了乙個msghdr結構以及它指向的各種資訊。圖中假設程序即將對乙個udp套接字呼叫recvmsg:

對於這兩個函式,區分兩個標誌變數,乙個是傳遞值的flags引數,乙個是所傳遞msghdr結構的msg_flags成員,傳遞的是引用,因此傳遞給函式的是該結構的位址。

只有recvmsg使用msg_flags成員。recvmsg被呼叫時,flags引數被複製到msg_flags成員,並由核心使用其值驅動接收處理過程。

flags引數值以及recvfrom可能返回的msg_flag成員值:

recvmsg返回的7個標誌:

msg_bcast:它的返回條件是本資料報作為鏈路層廣播收取或者其目的ip位址是乙個廣播位址。

msg_mcast:它的返回條件是本資料報作為鏈路層多播收取

msg_trunc:本標誌的返回條件是本資料報被截斷

msg_ctrunc:本標誌的返回條件是本資料報的輔助資料被截斷

msg_eor:本標誌的返回條件是返回資料結束的乙個邏輯記錄。

msg_oob:本標誌絕不為tcp帶外資料返回。

msg_notification:本標誌由sctp接受者返回。

高階I O函式

include intpipe int fd 2 要想實現雙向的資料傳輸,應該使用兩個管道。管道內部傳輸的資料時位元組流,這和tcp位元組流的概念相同。但tcp寫入多少位元組的資料決定對方的接受視窗和擁塞視窗,而管道本身有乙個容量限制,預設是65536位元組。我們可以使用fcntl函式來修改管道容量...

高階I O函式之sendfile函式

sendfile函式在兩個檔案描述符之間傳遞資料 完全在核心中操作 從而避免了核心緩衝區和使用者緩衝區之間的資料拷貝,效率很高,被稱為零拷貝。函式定義為 include ssize t senfile int out fd,int in fd,off t offset,size t count in...

Linux 高階I O函式 dup函式

created by wenfan on 2021 2 6.include include include include include include include include include int main int argc,char ar const char ip ar 1 int...