生产企业网站欣赏中国icp备案网站
web/
2025/10/5 6:40:05/
文章来源:
生产企业网站欣赏,中国icp备案网站,南山做网站公司在哪里,cps推广平台使用readv和writev函数可以提高数据通信的效率#xff0c;它们的功能可以概括为**“对数据进行整合传输及发送”**。 即使用writev函数可以将分散在多个缓冲中的数据一并发送#xff0c;使用readv函数可以由多个缓冲分别接受#xff0c;所以适当使用他们可以减少I/O函数的调… 使用readv和writev函数可以提高数据通信的效率它们的功能可以概括为**“对数据进行整合传输及发送”**。 即使用writev函数可以将分散在多个缓冲中的数据一并发送使用readv函数可以由多个缓冲分别接受所以适当使用他们可以减少I/O函数的调用次数。 1.readv和writev函数
①readv函数 用于从文件描述符中读取数据并存储在多个缓冲区中。
ssize_t readv(
int fd, //文件描述符。
const struct iovec *iov, //指向 iovec 结构体数组的指针iovec 结构体定义了一个缓冲区。
int iovcnt//iovec 结构体数组的元素个数。
);//iovec 结构体
struct iovec {void *iov_base; //指向缓冲区的起始地址基地址size_t iov_len; //缓冲区的长度即需要传输的字节数
};
示例代码
#includestdio.h
#includesys/uio.h
#define BUF_SIZE 100
int main(int argc, char *argv[])
{struct iovec vec[2];char buf1[BUF_SIZE] {0, };char buf2[BUF_SIZE] {0, };int str_len;//设置两个缓存区第一个存储5个字节剩下的给第二个缓冲区vec[0].iov_base buf1;vec[0].iov_len 5;vec[1].iov_base buf2;vec[1].iov_len BUF_SIZE;str_len readv(0, vec, 2);//第一个参数是0,即接受键盘输入printf(Read total bytes: %d \n, str_len);printf(First message: %s \n, buf1);printf(Second message: %s \n, buf2);return 0;
}②writev()函数 用于将多个缓冲区中的数据写入文件描述符这种方法称为“聚集写”或“向量写”。
ssize_t writev(
int fd, //文件描述符
const struct iovec *iov, //指向 iovec 结构体数组的指针iovec 结构体定义了一个缓冲区。
int iovcnt//iovec 结构体数组的元素个数。
);//iovec 结构体
struct iovec {void *iov_base; //指向缓冲区的起始地址基地址size_t iov_len; //缓冲区的长度即需要传输的字节数
};
示例代码
#includestdio.h
#includesys/uio.hint main(int argc, char *argv[]){struct iovec vec[2];//有两个缓冲char buf1[] 1234567890;char buf2[] ABCDEFGHIJ;int str_len;vec[0].iov_base buf1;vec[0].iov_len 10;vec[1].iov_base buf2;vec[1].iov_len 10;str_len writev(1, vec, 2);//第一个参数是1,所以是向控制台输出puts();printf(writev bytes: %d \n, str_len);
}2.在Windows中实现紧急消息机制
在《TCP/IP网络编程》第十三章多种I/O函数1中已经基于Linux平台实现了MSG_OOB机制但是是基于Linux的信号处理机制所以无法直接移植到Windows平台。
若要在Windows平台上实现该机制则需要通过select()函数该函数简介参考《TCP/IP网络编程》第十二章I/O复用1
PSMSG_OOB在select()监视下会被视为异常数据 发送端代码
#includestdio.h
#includestdlib.h
#includewinsock2.h#define BUFSIZE 30
void ErrorHandling(char* message);int main(int argc, char* argv[]){WSADATA wsa;SOCKET hSocket;SOCKADDR_IN sendAddr;if(argc!3){printf(Usage : %s IP port\n, argv[0]);exit(1);}if(WSAStartup(MAKEWORD(2,2), wsa) ! 0){ErrorHandling(WSAStartup() error!);}hSocket socket(PF_INET, SOCK_STREAM, 0);memset(sendAddr, 0, sizeof(sendAddr));sendAddr.sin_family AF_INET;sendAddr.sin_addr.s_addr inet_addr(argv[1]);sendAddr.sin_port htons(atoi(argv[2]));if(connect(hSocket, (SOCKADDR*)sendAddr, sizeof(sendAddr)) SOCKET_ERROR)ErrorHandling(connect() error!);send(hSocket, 123, 3, 0);send(hSocket, 4, 1, MSG_OOB);//带外数据在select的监视中会被视为异常数据send(hSocket, 567, 3, 0);send(hSocket, 890, 3, MSG_OOB);//只把最后一个字节0作为紧急信息发送closesocket(hSocket);WSACleanup();return 0;
}void ErrorHandling(char* message){fputs(message, stderr);fputc(\n, stderr);exit(1);
}接受端代码
#includestdio.h
#includestdlib.h
#includewinsock2.h#define BUFSIZE 30
void ErrorHandling(char *);int main(int argc, char *argv[]){WSADATA wsa;SOCKET hAcptSock, hRecvSock;SOCKADDR_IN sendAdr, recvAdr;int sendAdrSz,strLen;char buf[BUFSIZE];int result;fd_set read,except,read_copy,except_copy;struct timeval timeout;if(argc ! 2){printf(Usage : %s port\n, argv[0]);exit(1);}if(WSAStartup(MAKEWORD(2,2), wsa) ! 0)ErrorHandling(WSAStartup() error!);hAcptSock socket(PF_INET, SOCK_STREAM, 0);if(hAcptSock INVALID_SOCKET)ErrorHandling(socket() error);memset(recvAdr, 0, sizeof(recvAdr));recvAdr.sin_family AF_INET;recvAdr.sin_addr.s_addr htonl(INADDR_ANY);recvAdr.sin_port htons(atoi(argv[1]));if(bind(hAcptSock, (SOCKADDR*)recvAdr, sizeof(recvAdr)) SOCKET_ERROR)ErrorHandling(bind() error);if(listen(hAcptSock, 5) SOCKET_ERROR)ErrorHandling(listen() error);sendAdrSz sizeof(sendAdr);hRecvSock accept(hAcptSock, (SOCKADDR*)sendAdr, sendAdrSz);FD_ZERO(read); // 清空reads集合FD_ZERO(except); // 清空except集合FD_SET(hRecvSock, read); // 将套接字添加到reads集合FD_SET(hRecvSock, except); // 将套接字添加到except集合while(1){read_copy read;except_copy except;timeout.tv_sec 5;timeout.tv_usec 0;result select(0, read_copy, 0, except_copy, timeout);//开始监视文件描可读数集和与异常集合if(result0){if(FD_ISSET(hRecvSock, except_copy)){//使用FD_ISSET宏检查套接字是否在异常集合中。//如果是表示发生了异常事件此时会调用recv函数并指定MSG_OOB标志来接收带外数据strLen recv(hRecvSock, buf, BUFSIZE-1, MSG_OOB);buf[strLen] 0;printf(urgent message: %s \n, buf);}if(FD_ISSET(hRecvSock, read_copy)){// 如果检测到读事件strLen recv(hRecvSock, buf, BUFSIZE-1, 0);if(strLen 0){break;closesocket(hRecvSock);}else{buf[strLen] 0;printf(normal message: %s, buf);}}}}closesocket(hAcptSock);closesocket(hRecvSock);WSACleanup();return 0;
}void ErrorHandling(char *message){fputs(message, stderr);fputc(\n, stderr);exit(1);
}优先接受MSG_OOB信息4和0。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/87214.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!