中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

云浮新興哪有做網(wǎng)站的企業(yè)網(wǎng)站推廣的方法

云浮新興哪有做網(wǎng)站的,企業(yè)網(wǎng)站推廣的方法,手機(jī)百度收錄網(wǎng)站嗎,蘇州網(wǎng)頁設(shè)計制作培訓(xùn)引言:網(wǎng)絡(luò)數(shù)據(jù)能夠正常到達(dá)用戶并且被接收是進(jìn)行網(wǎng)絡(luò)傳輸?shù)母灸康?amp;#xff0c;網(wǎng)絡(luò)傳輸?shù)臄?shù)據(jù)發(fā)送和接收有多種方案,本文章就對通過向量接收和發(fā)送等數(shù)據(jù)傳輸方式,并且對多種I/O模型進(jìn)詳細(xì)分析介紹。 目錄 一.I/O函數(shù) 1.1 recv和send rec…

引言:網(wǎng)絡(luò)數(shù)據(jù)能夠正常到達(dá)用戶并且被接收是進(jìn)行網(wǎng)絡(luò)傳輸?shù)母灸康?#xff0c;網(wǎng)絡(luò)傳輸?shù)臄?shù)據(jù)發(fā)送和接收有多種方案,本文章就對通過向量接收和發(fā)送等數(shù)據(jù)傳輸方式,并且對多種I/O模型進(jìn)詳細(xì)分析介紹。

目錄

一.I/O函數(shù)

1.1 recv和send

recv函數(shù)

send函數(shù)

1.2 readv和writev函數(shù)

readv函數(shù)

writev函數(shù)

1.3?recvmsg和recvmsg函數(shù)?

recvmsg函數(shù)

sendmsg函數(shù)

1.4 客戶—服務(wù)器實例

服務(wù)器端代碼:

客戶端代碼:

二.I/O模型介紹

2.1 阻塞I/O(Blocking I/O)

2.2非阻塞I/O(Non-blocking I/O)

2.3I/O多路復(fù)用(I/O Multiplexing)

2.4信號驅(qū)動I/O(Signal-driven I/O)

2.5異步I/O(Asynchronous I/O)

三.監(jiān)視函數(shù)?

3.1select和pselect

select函數(shù)

pselect函數(shù)

3.2poll函數(shù)和ppoll函數(shù)

poll函數(shù)

ppoll函數(shù)

四.總結(jié)


一.I/O函數(shù)

1.1 recv和send

在網(wǎng)絡(luò)編程中,recv?和?send?函數(shù)是用于在套接字上進(jìn)行數(shù)據(jù)傳輸?shù)膬蓚€基本函數(shù)。它們是在Unix-like系統(tǒng)中的Berkeley套接字 API(也稱為BSD套接字API)的一部分,在Windows系統(tǒng)中也有對應(yīng)的實現(xiàn)。

recv函數(shù)

recv?函數(shù)用于從連接的套接字接收數(shù)據(jù)。函數(shù)原型如下:

ssize_t recv(int sockfd, void *buf, size_t len, int flags);
  • sockfd:指定接收數(shù)據(jù)的套接字文件描述符。

  • buf:指向緩沖區(qū)的指針,用于存放接收到的數(shù)據(jù)。

  • len:指定緩沖區(qū)的大小,即最多接收的數(shù)據(jù)量。

  • flags:指定接收數(shù)據(jù)的操作方式,可以是0或者以下一個或多個值的邏輯或:

    • MSG_OOB:接收帶外數(shù)據(jù)(Out-of-Band Data)。
    • MSG_PEEK:查看數(shù)據(jù)但不從接收隊列中移除數(shù)據(jù)。
    • MSG_WAITALL:等待所有請求的數(shù)據(jù),直到請求的數(shù)量被接收為止。
    • 等等。

返回值:

  • 成功時,返回接收到的字節(jié)數(shù)。
  • 如果連接被對方關(guān)閉,返回0。
  • 出錯時,返回-1,并設(shè)置errno來指示錯誤。

send函數(shù)

send?函數(shù)用于向連接的套接字發(fā)送數(shù)據(jù)。函數(shù)原型如下:

ssize_t send(int sockfd, const void *buf, size_t len, int flags);

參數(shù)說明:

  • sockfd:指定發(fā)送數(shù)據(jù)的套接字文件描述符。

  • buf:指向要發(fā)送數(shù)據(jù)的指針。

  • len:指定要發(fā)送數(shù)據(jù)的長度。

  • flags:指定發(fā)送數(shù)據(jù)的操作方式,可以是0或者以下一個或多個值的邏輯或:

    • MSG_OOB:發(fā)送帶外數(shù)據(jù)。
    • MSG_DONTROUTE:發(fā)送數(shù)據(jù)時不通過網(wǎng)關(guān)。
    • 等等。

返回值:

  • 成功時,返回發(fā)送的字節(jié)數(shù)。
  • 出錯時,返回-1,并設(shè)置errno來指示錯誤。

1.2 readv和writev函數(shù)

readv?和?writev?函數(shù)是 Unix 和類 Unix 操作系統(tǒng)中的系統(tǒng)調(diào)用,它們允許程序在一次操作中從多個緩沖區(qū)讀取數(shù)據(jù)或?qū)?shù)據(jù)寫入多個緩沖區(qū)。這些函數(shù)對于分散讀(scatter read)和集中寫(gather write)操作非常有用。

readv函數(shù)

readv?函數(shù)用于從文件描述符讀取數(shù)據(jù)到多個緩沖區(qū)中。函數(shù)原型如下:

ssize_t readv(int fd, const struct iovec *iov, int iovcnt);

參數(shù)說明:

  • fd:指定要讀取數(shù)據(jù)的文件描述符。
  • iov:指向?iovec?結(jié)構(gòu)數(shù)組的指針,每個?iovec?結(jié)構(gòu)指定一個緩沖區(qū)。
  • iovcnt:指定?iov?數(shù)組中?iovec?結(jié)構(gòu)的數(shù)量。

iovec?結(jié)構(gòu)定義如下:

struct iovec {void  *iov_base; /* Starting address */size_t iov_len;  /* Number of bytes to transfer */
};
  • iov_base:指向數(shù)據(jù)緩沖區(qū)的指針。
  • iov_len:指定緩沖區(qū)的長度。

返回值:

  • 成功時,返回讀取的總字節(jié)數(shù)。
  • 如果遇到文件結(jié)束,返回0。
  • 出錯時,返回-1,并設(shè)置errno來指示錯誤。

writev函數(shù)

writev?函數(shù)用于將多個緩沖區(qū)的數(shù)據(jù)寫入到文件描述符。函數(shù)原型如下:

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

參數(shù)說明:

  • fd:指定要寫入數(shù)據(jù)的文件描述符。
  • iov:指向?iovec?結(jié)構(gòu)數(shù)組的指針,每個?iovec?結(jié)構(gòu)指定一個數(shù)據(jù)源緩沖區(qū)。
  • iovcnt:指定?iov?數(shù)組中?iovec?結(jié)構(gòu)的數(shù)量。

返回值:

  • 成功時,返回寫入的總字節(jié)數(shù)。
  • 出錯時,返回-1,并設(shè)置errno來指示錯誤。

1.3?recvmsg和recvmsg函數(shù)?

recvmsg?和?sendmsg?函數(shù)是 Unix 和類 Unix 操作系統(tǒng)中的系統(tǒng)調(diào)用,它們提供了比?recv?和?send?更高級的接口,用于在套接字上發(fā)送和接收數(shù)據(jù)。這些函數(shù)支持更多的功能,如scatter/gather I/O、控制消息的發(fā)送和接收,以及帶外數(shù)據(jù)。

recvmsg函數(shù)

recvmsg?函數(shù)用于從套接字接收數(shù)據(jù),并可以接收輔助數(shù)據(jù)(ancillary data)。函數(shù)原型如下:

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

參數(shù)說明:

  • sockfd:指定接收數(shù)據(jù)的套接字文件描述符。

  • msg:指向?msghdr?結(jié)構(gòu)的指針,該結(jié)構(gòu)包含了接收操作的所有參數(shù)。

  • flags:指定接收數(shù)據(jù)的操作方式,可以是0或者以下一個或多個值的邏輯或:

    • MSG_OOB:接收帶外數(shù)據(jù)。
    • MSG_PEEK:查看數(shù)據(jù)但不從接收隊列中移除數(shù)據(jù)。
    • MSG_WAITALL:等待所有請求的數(shù)據(jù),直到請求的數(shù)量被接收為止。
    • 等等。

msghdr?結(jié)構(gòu)定義如下:

struct msghdr {void         *msg_name;       /* Optional address */socklen_t     msg_namelen;    /* Size of address */struct iovec *msg_iov;        /* Scatter/gather array */int           msg_iovlen;     /* # elements in msg_iov */void         *msg_control;    /* Ancillary data, see below */socklen_t     msg_controllen; /* Ancillary data buffer len */int           msg_flags;      /* Flags on received message */
};
  • msg_name?和?msg_namelen:用于接收對方地址信息(僅用于面向連接的套接字)。
  • msg_iov?和?msg_iovlen:指定分散讀的緩沖區(qū)數(shù)組?iovec?和其長度。
  • msg_control?和?msg_controllen:用于接收輔助數(shù)據(jù)和控制信息。
  • msg_flags:接收消息的標(biāo)志,由系統(tǒng)填充。

返回值:

  • 成功時,返回接收到的字節(jié)數(shù)。
  • 如果連接被對方關(guān)閉,返回0。
  • 出錯時,返回-1,并設(shè)置errno來指示錯誤。

sendmsg函數(shù)

sendmsg?函數(shù)用于向套接字發(fā)送數(shù)據(jù),并可以發(fā)送輔助數(shù)據(jù)。函數(shù)原型如下:

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

參數(shù)說明:

  • sockfd:指定發(fā)送數(shù)據(jù)的套接字文件描述符。

  • msg:指向?msghdr?結(jié)構(gòu)的指針,該結(jié)構(gòu)包含了發(fā)送操作的所有參數(shù)。

  • flags:指定發(fā)送數(shù)據(jù)的操作方式,可以是0或者以下一個或多個值的邏輯或:

    • MSG_OOB:發(fā)送帶外數(shù)據(jù)。
    • MSG_DONTROUTE:發(fā)送數(shù)據(jù)時不通過網(wǎng)關(guān)。
    • 等等。

返回值:

  • 成功時,返回發(fā)送的字節(jié)數(shù)。
  • 出錯時,返回-1,并設(shè)置errno來指示錯誤。

1.4 客戶—服務(wù)器實例

這個服務(wù)器的功能主要是返回客戶端輸入的數(shù)據(jù)長度,其中使用了I/O函數(shù)中的readv和writev。

服務(wù)器端代碼:

(我這個代碼涉及到許多前面的基礎(chǔ)知識,需要了解的就可以看我上一篇博客:

寫文章-CSDN創(chuàng)作中心socket套接字函數(shù)-CSDN博客寫文章-CSDN創(chuàng)作中心)

#include<t_stdio.h>
#include<t_file.h>
#include<stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>
#include<unistd.h>
static struct iovec*vs=NULL;
void sig_process(int signo){//信號處理函數(shù)printf("catch a exit signal..\n");free(vs);_exit(0);
}#define port 8888//端口號
#define backlog 2//最大監(jiān)聽數(shù)量//業(yè)務(wù)處理邏輯
void process_conn_server(int s){char buffer [30];ssize_t size=0; //向量的緩沖區(qū)//申請3個向量空間struct iovec * v = (struct iovec *)malloc(3*sizeof(struct iovec));if(!v) E_MSG("malloc",-1);vs = v;//掛接全局變量,易于釋放管理v[0].iov_base= buffer;//每個向量十個地址空間v[1].iov_base= buffer+10;v[2].iov_base= buffer+20;v[0].iov_len = v[1].iov_len = v[2].iov_len = 10;//初始化長度為10for(;;){size = readv(s, v , 3);// 從套接字中讀取數(shù)據(jù)放入數(shù)據(jù)緩沖區(qū)if(size == 0){return ;}//構(gòu)建響應(yīng)字符sprintf(v[0].iov_base,"%d",size);sprintf(v[1].iov_base,"bytes alter");sprintf(v[2].iov_base,"ogether\n");//設(shè)置寫入數(shù)據(jù)的長度v[0].iov_len = strlen(v[0].iov_base);v[1].iov_len = strlen(v[1].iov_base);v[2].iov_len = strlen(v[2].iov_base);writev(s , v , 3);//發(fā)送給客戶端}}
int main(int argc ,char * argv[])
{int ss ,sc;//服務(wù)器和客戶端的套接字文件描述符struct  sockaddr_in server_addr;//服務(wù)器地址結(jié)構(gòu)struct  sockaddr_in client_addr;//客戶端地址結(jié)構(gòu)pid_t pid;//創(chuàng)建子進(jìn)程進(jìn)行分叉進(jìn)行signal(SIGINT,sig_process);//添加sigint信號到信號掩碼signal(SIGPIPE,sig_process);ss = socket(AF_INET,SOCK_STREAM,0);// 創(chuàng)建服務(wù)器套接字if(ss < 0) E_MSG("socket",-1);bzero(&server_addr,sizeof(server_addr));//將地址清零server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = htons(INADDR_ANY);//本地地址server_addr.sin_port=htons(port);//設(shè)置端口//綁定本地到套接字符int err = bind(ss,(struct  sockaddr * )&server_addr,sizeof(server_addr));if(err < 0)E_MSG("bind",-1);err = listen(ss,backlog);//創(chuàng)建監(jiān)聽隊列for(;;){int addrlen = sizeof(struct sockaddr);sc = accept(ss,(struct sockaddr * )&client_addr,&addrlen);//獲取用戶套接字if(sc < 0)continue;//客戶端出錯,結(jié)束這次循環(huán),繼續(xù)監(jiān)聽客戶;pid = fork();//創(chuàng)建新的子進(jìn)程來處理當(dāng)前連接客戶端;if(pid==0){close(ss);// 子進(jìn)程中關(guān)閉服務(wù)端process_conn_server(sc);}else {close(sc);//父進(jìn)程關(guān)閉客戶端連接,繼續(xù)監(jiān)聽;}}return 0;
}

客戶端代碼:

#include<t_stdio.h>
#include<t_file.h>
#include<stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>
#include<unistd.h>
#define port 8888
static int s;
static struct iovec*vc=NULL;
void  sig_proccess(int signo){printf("catch a exit signal..\n");free(vc);_exit(0);
}void sig_pipe(int signo){printf("catch a sigpipe signal..\n");free(vc);_exit(0);}//業(yè)務(wù)處理函數(shù)
void process_conn_client(int s){char buffer [30];ssize_t size=0; //向量的緩沖區(qū)//申請3個向量空間struct iovec * v = (struct iovec *)malloc(3*sizeof(struct iovec));if(!v) E_MSG("malloc",-1);vc = v;//掛接全局變量,易于釋放管理v[0].iov_base= buffer;//每個向量十個地址空間v[1].iov_base= buffer+10;v[2].iov_base= buffer+20;v[0].iov_len = v[1].iov_len = v[2].iov_len = 10;//初始化長度為10int i=0;for(;;){//從標(biāo)準(zhǔn)輸入中讀取數(shù)據(jù)放入緩沖區(qū)buffer中size = read(0,v[0].iov_base,10);//只有十個字節(jié)if(size>0){v[0].iov_len = size;writev(s,v,1);//發(fā)送給服務(wù)器v[0].iov_len = v[1].iov_len = v[2].iov_len = 10;size=readv(s,v,3);//從服務(wù)器讀取數(shù)據(jù)for(i = 0;i<3;i++){if(v[i].iov_len > 0){write(1,v[i].iov_base,v[i].iov_len);//將服務(wù)區(qū)處理后數(shù)據(jù)輸出}}                  }}}
int main(int argc ,char * argv[])
{struct sockaddr_in server_addr;//服務(wù)器結(jié)構(gòu)地址int err;if(argc == 1){printf("pls input server addr\n");return 0;}//沒有輸入指令參數(shù)signal(SIGINT,sig_proccess);signal(SIGPIPE,sig_pipe);//設(shè)置信號掩碼s = socket(AF_INET,SOCK_STREAM,0);//創(chuàng)建客戶端套接字if(s < 0)E_MSG("socket",-1);//設(shè)置服務(wù)器地址bzero(&server_addr,sizeof(server_addr));//將地址清0server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = htons(INADDR_ANY);//本地地址server_addr.sin_port=htons(port);//設(shè)置端口inet_pton(AF_INET,argv[1],&server_addr.sin_addr);//將用戶輸入的字符串ip轉(zhuǎn)化為二進(jìn)制ipconnect(s,(struct sockaddr *)&server_addr,sizeof(server_addr));//連接服務(wù)器process_conn_client(s);return 0;
}

?對于這兩個代碼,大家可以仔細(xì)閱讀,我寫了非常詳細(xì)的注釋,包括信號的處理,業(yè)務(wù)邏輯的處理等等,可以將我們整個基礎(chǔ)網(wǎng)絡(luò)知識串聯(lián)起來!

二.I/O模型介紹

網(wǎng)絡(luò)編程中的I/O模型主要影響程序如何處理網(wǎng)絡(luò)套接字的讀寫操作。以下是幾種常見的I/O模型:

2.1 阻塞I/O(Blocking I/O)

?阻塞I/O模型是最簡單的I/O模型。當(dāng)發(fā)起一個I/O操作(如讀或?qū)?#xff09;時,如果數(shù)據(jù)未準(zhǔn)備好,程序會阻塞直到操作完成。在這段時間內(nèi),程序無法執(zhí)行其他任務(wù)。

// 阻塞讀
char buffer[1024];
read(socket, buffer, sizeof(buffer));

2.2非阻塞I/O(Non-blocking I/O)

在非阻塞I/O模型中,I/O操作不會阻塞程序。如果數(shù)據(jù)未準(zhǔn)備好,I/O操作會立即返回一個錯誤碼(通常是EAGAINEWOULDBLOCK)。程序需要定期輪詢檢查數(shù)據(jù)是否準(zhǔn)備好.

// 設(shè)置套接字為非阻塞模式
int flags = fcntl(socket, F_GETFL, 0);
fcntl(socket, F_SETFL, flags | O_NONBLOCK);// 非阻塞讀
char buffer[1024];
while (read(socket, buffer, sizeof(buffer)) == -1 && errno == EAGAIN) {// 數(shù)據(jù)未準(zhǔn)備好,繼續(xù)做其他事情
}

2.3I/O多路復(fù)用(I/O Multiplexing)

?I/O多路復(fù)用允許程序同時監(jiān)視多個文件描述符,等待一個或多個變得“就緒”。這可以通過select、poll、epoll(Linux特有)或kqueue(BSD特有)系統(tǒng)調(diào)用來實現(xiàn)。

// 使用select進(jìn)行I/O多路復(fù)用
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(socket, &readfds);select(socket + 1, &readfds, NULL, NULL, NULL);if (FD_ISSET(socket, &readfds)) {char buffer[1024];read(socket, buffer, sizeof(buffer));
}

2.4信號驅(qū)動I/O(Signal-driven I/O)

信號驅(qū)動I/O模型中,程序通過sigaction系統(tǒng)調(diào)用請求內(nèi)核在文件描述符就緒時發(fā)送一個信號。當(dāng)數(shù)據(jù)準(zhǔn)備好時,內(nèi)核會發(fā)送一個SIGIO信號,程序可以在信號處理函數(shù)中處理數(shù)據(jù)。?

// 設(shè)置信號處理函數(shù)
struct sigaction sa;
sa.sa_handler = io_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
sigaction(SIGIO, &sa, NULL);// 設(shè)置套接字的所有者
fcntl(socket, F_SETOWN, getpid());// 開啟信號驅(qū)動I/O
int flags = fcntl(socket, F_GETFL, 0);
fcntl(socket, F_SETFL, flags | O_ASYNC);

2.5異步I/O(Asynchronous I/O)

?異步I/O模型中,程序發(fā)起I/O操作后,立即返回,無需等待數(shù)據(jù)準(zhǔn)備好。當(dāng)操作完成時,程序會收到通知。這種模型通常通過aio_readaio_write等系統(tǒng)調(diào)用來實現(xiàn)。

// 異步讀
aiocb aio;
memset(&aio, 0, sizeof(aio));
aio.aio_fildes = socket;
aio.aio_buf = buffer;
aio.aio_nbytes = sizeof(buffer);
aio.aio_offset = 0;aio_read(&aio);

每種I/O模型都有其適用的場景。例如,阻塞I/O適用于簡單應(yīng)用,非阻塞I/O和I/O多路復(fù)用適用于需要處理多個套接字的應(yīng)用,而異步I/O適用于需要高性能和低延遲的應(yīng)用。在選擇合適的I/O模型時,需要考慮應(yīng)用的特定需求和性能。

三.監(jiān)視函數(shù)?

3.1select和pselect

在網(wǎng)絡(luò)編程中,select?和?pselect?函數(shù)是用于多路復(fù)用(I/O multiplexing)的系統(tǒng)調(diào)用,它們允許程序同時監(jiān)視多個文件描述符,以判斷它們是否準(zhǔn)備好進(jìn)行讀、寫或異常(錯誤)操作。

select函數(shù)

select?函數(shù)的原型如下:

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

參數(shù)說明:

  • nfds:需要檢查的最高文件描述符加1。通常設(shè)置為最大的文件描述符加上1。
  • readfds:指向一組文件描述符的指針,這些文件描述符需要檢查是否準(zhǔn)備好讀取數(shù)據(jù)。
  • writefds:指向一組文件描述符的指針,這些文件描述符需要檢查是否準(zhǔn)備好寫入數(shù)據(jù)。
  • exceptfds:指向一組文件描述符的指針,這些文件描述符需要檢查是否發(fā)生異常。
  • timeout:指向?timeval?結(jié)構(gòu)的指針,用于指定?select?應(yīng)該阻塞等待的最大時間。如果設(shè)置為?NULLselect?將無限期地等待;如果設(shè)置為0,select?將立即返回。

timeval?結(jié)構(gòu)定義如下:

struct timeval {long    tv_sec;         /* seconds */long    tv_usec;        /* microseconds */
};

返回值:

  • 成功時,返回準(zhǔn)備好的文件描述符的數(shù)量。
  • 如果超時,返回0。
  • 出錯時,返回-1,并設(shè)置errno來指示錯誤。

使用?select?時,需要使用?FD_ZERO、FD_SET?和?FD_CLR?宏來操作?fd_set?集合。

pselect函數(shù)

pselect?函數(shù)與?select?類似,但它提供了一些額外的功能,特別是在處理信號方面。pselect?的原型如下:

int pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout, const sigset_t *sigmask);

參數(shù)說明:

  • 前四個參數(shù)與?select?函數(shù)相同。
  • timeout:指向?timespec?結(jié)構(gòu)的指針,用于指定?pselect?應(yīng)該阻塞等待的最大時間。timespec?結(jié)構(gòu)與?timeval?類似,但它使用秒和納秒來表示時間。
  • sigmask:指向?sigset_t?類型的一個信號集的指針,用于在?pselect?調(diào)用期間臨時替換進(jìn)程的信號掩碼。這意味著?pselect?在等待文件描述符就緒時會阻塞指定的信號。

timespec?結(jié)構(gòu)定義如下:

struct timespec {time_t  tv_sec;         /* seconds */long    tv_nsec;        /* nanoseconds */
};

返回值:

  • 成功時,返回準(zhǔn)備好的文件描述符的數(shù)量。
  • 如果超時,返回0。
  • 出錯時,返回-1,并設(shè)置errno來指示錯誤。

例子:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/select.h>int main() {fd_set readfds;struct timeval timeout;int result;FD_ZERO(&readfds);FD_SET(0, &readfds); // 監(jiān)視標(biāo)準(zhǔn)輸入(文件描述符0)timeout.tv_sec = 5; // 設(shè)置超時時間為5秒timeout.tv_usec = 0;result = select(1, &readfds, NULL, NULL, &timeout);if (result == -1) {perror("select");exit(EXIT_FAILURE);} else if (result > 0) {printf("Data is available to read.\n");} else {printf("Timeout occurred.\n");}return 0;
}

在這個例子中,我們使用?select?來監(jiān)視標(biāo)準(zhǔn)輸入(文件描述符0),設(shè)置超時時間為5秒。如果在這段時間內(nèi)有數(shù)據(jù)可讀,select?將返回大于0的值;如果超時,將返回0;如果發(fā)生錯誤,將返回-1。

3.2poll函數(shù)和ppoll函數(shù)

?poll?和?ppoll?函數(shù)是 Unix 和類 Unix 操作系統(tǒng)中的系統(tǒng)調(diào)用,用于多路復(fù)用(I/O multiplexing),允許程序同時監(jiān)視多個文件描述符的讀寫狀態(tài)。與?select?和?pselect?函數(shù)相比,poll?和?ppoll?提供了更豐富的接口和更好的性能。

poll函數(shù)

poll?函數(shù)的原型如下:

int poll(struct pollfd *fds, nfds_t nfds, int timeout);

參數(shù)說明:

  • fds:指向一個?pollfd?結(jié)構(gòu)數(shù)組的指針,每個結(jié)構(gòu)描述了一個要監(jiān)視的文件描述符。
  • nfds:指定?fds?數(shù)組中?pollfd?結(jié)構(gòu)的數(shù)量。
  • timeout:指定?poll?應(yīng)該阻塞等待的最大時間(毫秒)。如果設(shè)置為-1,poll?將無限期地等待;如果設(shè)置為0,poll?將立即返回。

pollfd?結(jié)構(gòu)定義如下:

struct pollfd {int   fd;         /* file descriptor */short events;     /* requested events */short revents;    /* returned events */
};
  • fd:要監(jiān)視的文件描述符。
  • events:請求監(jiān)視的 events(通過位掩碼指定)。
  • revents:返回時,表示實際發(fā)生的事件(通過位掩碼指定)。

events?和?revents?可以是以下標(biāo)志的組合(定義在?<poll.h>?頭文件中):

  • POLLIN:有數(shù)據(jù)可讀。
  • POLLOUT:可以寫數(shù)據(jù)。
  • POLLERR:發(fā)生錯誤。
  • POLLHUP:掛起。
  • POLLNVAL:無效的請求。

返回值:

  • 成功時,返回準(zhǔn)備好的文件描述符的數(shù)量。
  • 如果超時,返回0。
  • 出錯時,返回-1,并設(shè)置errno來指示錯誤。

ppoll函數(shù)

ppoll?函數(shù)與?poll?類似,但它提供了一些額外的功能,特別是在處理信號方面。ppoll?的原型如下:

int ppoll(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout, const sigset_t *sigmask);

參數(shù)說明:

  • 前三個參數(shù)與?poll?函數(shù)相同。
  • timeout:指向?timespec?結(jié)構(gòu)的指針,用于指定?ppoll?應(yīng)該阻塞等待的最大時間。timespec?結(jié)構(gòu)與?timeval?類似,但它使用秒和納秒來表示時間。
  • sigmask:指向?sigset_t?類型的一個信號集的指針,用于在?ppoll?調(diào)用期間臨時替換進(jìn)程的信號掩碼。這意味著?ppoll?在等待文件描述符就緒時會阻塞指定的信號。

返回值:

  • 成功時,返回準(zhǔn)備好的文件描述符的數(shù)量。
  • 如果超時,返回0。
  • 出錯時,返回-1,并設(shè)置errno來指示錯誤。

例子:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <poll.h>int main() {struct pollfd fds[1];int result;fds[0].fd = 0; // 監(jiān)視標(biāo)準(zhǔn)輸入(文件描述符0)fds[0].events = POLLIN; // 監(jiān)視可讀事件result = poll(fds, 1, 5000); // 設(shè)置超時時間為5000毫秒if (result == -1) {perror("poll");exit(EXIT_FAILURE);} else if (result > 0) {if (fds[0].revents & POLLIN) {printf("Data is available to read.\n");}} else {printf("Timeout occurred.\n");}return 0;
}

?在這個例子中,我們使用?poll?來監(jiān)視標(biāo)準(zhǔn)輸入(文件描述符0),設(shè)置超時時間為5000毫秒。如果在這段時間內(nèi)有數(shù)據(jù)可讀,poll?將返回大于0的值;如果超時,將返回0;如果發(fā)生錯誤,將返回-1。

四.總結(jié)

這篇文章對數(shù)據(jù)I/O進(jìn)行了整體的介紹,包括recv ,send, readv , writev,recmsg , sendmsg等I/O函數(shù),并且給了很多例子,來介紹I/O的各種模型及其使用,相信經(jīng)過這篇文章的學(xué)習(xí),大家對網(wǎng)絡(luò)編程中的I/O操作能有個整體認(rèn)知!!!

http://www.risenshineclean.com/news/3755.html

相關(guān)文章:

  • 西部數(shù)據(jù)網(wǎng)站管理助手搜索引擎排名2020
  • 旅游手機(jī)網(wǎng)站開發(fā)東莞做網(wǎng)站公司
  • 網(wǎng)站上線 郵件群發(fā)模板網(wǎng)站搭建需要多少錢?
  • 怎么開發(fā)一款小程序優(yōu)化網(wǎng)站價格
  • 企業(yè)在公司做的網(wǎng)站看不到seo營銷網(wǎng)站的設(shè)計標(biāo)準(zhǔn)
  • 做網(wǎng)站的軟件公司百度競價關(guān)鍵詞
  • 東莞專業(yè)做網(wǎng)站的公司北京網(wǎng)站seo招聘
  • 網(wǎng)站網(wǎng)站建設(shè)網(wǎng)頁設(shè)計網(wǎng)站建設(shè)需要多少錢?
  • 阿里云服務(wù)器上的網(wǎng)站怎么做修改谷歌瀏覽器 免費(fèi)下載
  • 余姚網(wǎng)站建設(shè)哪家好商業(yè)推廣軟文范例
  • 企業(yè)單頁網(wǎng)站模板推廣普通話奮進(jìn)新征程
  • 網(wǎng)站如何做軟文推廣湯陰縣seo快速排名有哪家好
  • 做零食的網(wǎng)站有哪些線上營銷推廣方案
  • 織夢企業(yè)網(wǎng)站源碼長沙網(wǎng)站制作主要公司
  • 口碑好網(wǎng)站制作公司哪家好地推
  • 網(wǎng)站怎么做百度商橋百度客服電話人工服務(wù)熱線電話
  • 網(wǎng)站建設(shè)推廣方案排名優(yōu)化工具
  • 安陽市地圖蘇州seo快速優(yōu)化
  • 做代練網(wǎng)站能備案營銷網(wǎng)絡(luò)推廣哪家好
  • wordpress 韓版 企業(yè)seo模擬點擊
  • 達(dá)州住房和城鄉(xiāng)建設(shè)廳網(wǎng)站中國十大熱門網(wǎng)站排名
  • 怎么在wordpress建英文網(wǎng)站杭州seo價格
  • 中山精品網(wǎng)站建設(shè)機(jī)構(gòu)外貿(mào)網(wǎng)站如何推廣優(yōu)化
  • 物流網(wǎng)站建設(shè)公司外貿(mào)谷歌推廣怎么樣
  • 網(wǎng)站程序授權(quán)碼如何聯(lián)系百度人工客服
  • 域名網(wǎng)站可以做多個品牌產(chǎn)品嗎軟文推廣策劃方案
  • 國外專門做童裝的網(wǎng)站網(wǎng)絡(luò)營銷的概念和含義
  • 長春網(wǎng)站開發(fā)公司哪家好在線推廣
  • 網(wǎng)站置頂代碼100個成功營銷策劃案例
  • 網(wǎng)站建設(shè)銷售問答seo查詢seo