UNP学习 高级I/O函数
生活随笔
收集整理的這篇文章主要介紹了
UNP学习 高级I/O函数
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
首先為一個I/O函數設置超時,這有三種方法。然后是三個read和write函數的變體:
- recv和send,他們可以把含有標志的第四個參數從進程傳給內核;
- readv和writev這兩個函數可以指定一個緩沖區的向量以輸入或輸出數據;
- recvmsg和sendmsg在其他I/O函數的所有功能基礎上結合了新的接收和發送輔助數據的能力。
?
一、套接口超時
有三種方法給套接口上的I/O操作設置超時。
?
二、recv和send函數
#include <sys/socket.h>ssize_t recv(int sockfd, void *buff, size_t nbytes, int flags); ssize_t send(int sockfd, const void *buff, size_t nbytes, int flags); 返回:成功返回讀入或寫出的字節數,出錯返回-1前三個參數與read和write相同,flags的值或為0,或是一個或多個常值的邏輯或構成
MSG_DONTROUTE:不查路由表
MSG_DONTWAIT:本操作不阻塞
MSG_OOB:發送或接收帶外數據
MSG_PEEK:查看外來的消息
MSG_WAITTALL:等待所有數據
如果進程需要讓內核來更新標志,就必須用recvmsg代替recv或recvfrom。
?
三、readv和writev函數
#include <sys/uio.h>ssize_t readv(int filedes, const struct iovec *iov, int iovcnt); ssize_t writev(int filedes, const struct iovec *iov, int iovcnt); 返回:讀到或寫出的字節數,出錯時為-1 struct iovec {void *iov_base; /* starting address of buffer */size_t iov_len; /* size of buffer */ };readv和writev可用于任何描述字,不僅限于套接口描述字。
?
四、recvmsg和sendmsg函數
實際上,可以用recvmsg代替read、readv、readcv和recvfrom。
#include <sys/socket.h>ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags); ssize_t sendmsg(int sockfd, struct msghdr *msg, int flags); 返回:成功時為讀入或寫出的字符數,出錯-1struct msghdr {void *msg_name; /* protocol address */用于未經連接的套接口socklen_t msg_namelen; /* size of protocol address */未經連接的套接口struct iovec *msg_iov; /* scatter/gather array */指明輸入或輸出的緩沖區數組size_t msg_iovlen; /* # elements in msg_iov */void *msg_control; /* ancillary data, must be aligned for a cmsghdr structure */socklen_t msg_controllen; /* length of ancillary data */指明可選輔助數據的位置和大小int msg_flags; /* flags returned by recvmsg() */標志變量 };?輔助數據由一個或多個輔助數據對象組成,每個對象一個cmsghdr結構開頭,該結構在<sys/socket.h>中定義
struct cmsghdr{socklen_t cmsg_len; /* length in bytes, including this structure */字節長度int cmsg_level; /* originating protocol */初始協議int cmsg_type; /* protocol-specific type */協議指定類型/* followed by unsigned char cmsg_data[] */真正的控制消息數據 };?
因為由recvmsg返回的輔助數據可以包括任意數目的輔助數據對象,為了對應用程序屏蔽可能出現的填充字節。
在<sys/socket.h>中定義了以下五個宏,以簡化對輔助數據的處理。
#include <sys/socket.h> #include <sys/param.h> /* for ALIGN macro on many implementations */ struct cmsghdr *CMSG_FIRSTHDR(struct msghdr *mhdrptr); 返回:指向第一個cmsghdr結構的指針,無輔助數據時為NULL struct cmsghdr *CMSG_NXTHDR(struct msghdr *mhdrptr, struct cmsghdr *cmsgptr); 返回:指向下一個cmsghdr結構的指針,不再有輔助數據對象時為NULL unsigned char *CMSG_DATA(struct cmsghdr *cmsgptr); 返回:指向與cmsghdr結構關聯的數據的第一個字節的指針 unsigned int CMSG_LEN(unsigned in length); 返回:給定數量下存儲在cmsg_len中的值 unsigned int CMSG_SPACE(unsigned int length); 返回:給定數據量下一個輔助數據對象的總大小一些使用例子:
struct msghdr msg;
struct cmsghdr *cmptr;
cmptr = CMSG_FIRSTHDR(&msg);
cmptr->cmsg_len = CMSG_LEN(sizeof(int));
cmptr->cmsg_level = SOL_SOCKET;
cmptr->cmsg_type = SCM_RIGHTS; /* send file description */
*((int *)CMSG_DATA(cmptr)) = sendfd;
?使用msghdr的列子:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <unistd.h> 4 #include <errno.h> 5 #include <string.h> 6 #include <sys/types.h> 7 #include <sys/socket.h> 8 9 int main(int argc, char *argv[]) 10 { 11 int ret; 12 int sock[2]; 13 struct msghdr msg; 14 struct iovec iov[1]; 15 char send_buf[100] = "Hello"; 16 17 struct msghdr msgr; 18 struct iovec iovr[1]; 19 char recv_buf[100]; 20 21 ret = socketpair(AF_LOCAL, SOCK_STREAM, 0, sock); 22 if(ret == -1) { 23 printf("socketpair err\n"); 24 return 1; 25 } 26 27 /* sock[1] send data to local */ 28 bzero(&msg, sizeof(msg)); 29 msg.msg_name = NULL; 30 msg.msg_namelen = 0; 31 iov[0].iov_base = send_buf; 32 iov[0].iov_len = sizeof(send_buf); 33 msg.msg_iov = iov; 34 msg.msg_iovlen = 1; 35 36 printf("Starting send data: \n"); 37 printf("Send data: %s\n", send_buf); 38 ret = sendmsg(sock[1], &msg, 0); 39 if(ret == -1) { 40 printf("sendmsg err\n"); 41 return -1; 42 } 43 printf("Send successful\n"); 44 45 /* sock[0] recv data to local */ 46 bzero(&msgr, sizeof(msgr)); 47 msgr.msg_name = NULL; 48 msgr.msg_namelen = 0; 49 iovr[0].iov_base = recv_buf; 50 iovr[0].iov_len = sizeof(recv_buf); 51 msgr.msg_iov = iovr; 52 msgr.msg_iovlen = 1; 53 ret = recvmsg(sock[0], &msgr, 0); 54 if(ret == -1) { 55 printf("recvmsg err\n"); 56 return -1; 57 } 58 printf("Recv successful\n"); 59 printf("Recv data: %s\n", recv_buf); 60 61 close(sock[0]); 62 close(sock[1]); 63 64 return 0; 65 }運行結果:
$ ./a.outStarting send data: Send data: Hello Send successful Recv successful Recv data: Hello
?
轉載于:https://www.cnblogs.com/ch122633/p/8523244.html
總結
以上是生活随笔為你收集整理的UNP学习 高级I/O函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《梦断代码》阅读笔记之第8章至最后
- 下一篇: android Instrumentat