首先为一个I/O函数设置超时,这有三种方法。然后是三个read和write函数的变体:

  • recv和send,他们可以把含有标志的第四个参数从进程传给内核;
  • readv和writev这两个函数可以指定一个缓冲区的向量以输入或输出数据;
  • recvmsg和sendmsg在其他I/O函数的所有功能基础上结合了新的接收和发送辅助数据的能力。

一、套接口超时

有三种方法给套接口上的I/O操作设置超时。

  1. 调用alarm,在到达指定事件时产生SIGALRM信号。这涉及到信号处理,这一点随不同实现而变化,而且可能与进程中其他已有的alarm调用冲突。
  2. 使用select阻塞在等待I/O上,select内部有一个时间限制,以此代替在read或write调用上阻塞。
  3. 使用新的SO_RCVTIMEO和SO_SNDTIMEO套接口选项。这种方法存在一个问题,即并不是所有的实现都能支持这两个套接口选项。

二、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函数相关推荐

  1. python学习高级篇(part10)--类对象的特殊方法和特殊属性

    学习笔记,仅供参考,有错必纠 文章目录 python 学习高级篇 类对象的特殊方法之`__del__()` 类对象的特殊方法之`__getattr__()` 类对象的特殊方法之`__getitem__ ...

  2. python学习高级篇(part9)--对象的引用计数

    学习笔记,仅供参考,有错必纠 文章目录 python 学习高级篇 类对象的特殊方法之`__str__()` 类对象的特殊方法之`__new__()` 对象的引用计数 什么是引用计数 对象的引用计数加1 ...

  3. python学习高级篇(part7)--特殊属性和特殊方法

    学习笔记,仅供参考,有错必纠 文章目录 python 学习高级篇 特殊属性和特殊方法 获取对象的信息之特殊属性`__dict__` 获取对象的信息之反射 类对象的特殊方法`__len__()` pyt ...

  4. jquery学习笔记及常用函数封装

    二.JQuery 学习笔记及常用函数封装 https://download.csdn.net/download/weixin_42530002/13087988 1.JQuery入门 (1).css选 ...

  5. python学习——高级教程

    Python学习 高级教程 目录 1. Python面向对象 2. Python正则表达式 3. Python多线程 4. Python GUI编程 5. Python JSON 一.Python面向 ...

  6. c++学习笔记内联函数,函数重载,默认参数

    c++学习笔记内联函数,函数重载,默认参数 1 inline内联函数 C++中的const常量可以替代宏常数定义,如: const int A = 3;  #define A 3 C++中是否有解决 ...

  7. php函数知识点,php入门学习知识点七 PHP函数的基本应用_php基础

    /* * 简单的函数 */ function fontBold($con){ return "$con"; } $str="简单的函数测试!"; echo &q ...

  8. Linux高性能server编程——高级I/O函数

     高级I/O函数 pipe函数 pipe函数用于创建一个管道,实现进程间的通信. #include <unistd.h> int pipe(int pipefd[2]); 通过pipe ...

  9. python学习高级篇(part8)--类对象的特殊方法

    学习笔记,仅供参考,有错必纠 文章目录 python 学习高级篇 类对象的特殊方法之`__iter__()`和`__next__()` 类对象的特殊方法之`__add__()`和`__radd__() ...

最新文章

  1. FPGA最全科普总结
  2. Windows域信任关系建立全攻略
  3. 用缓动函数模拟物理动画
  4. 叮~ 量子位欢迎你加入AI群聊
  5. c++ opencv 通道转换
  6. poj-1384 Piggy-Bank
  7. ApiBoot - ApiBoot Quartz 使用文档
  8. 虚拟机VMware的Ubuntu下安装tensorflow详解
  9. C-Free简单介绍
  10. 第一次学游泳技巧_第一次学游泳作文600字(5篇)
  11. 微信小程序-----消息模版(最全解释)
  12. vuex中辅助函数写法
  13. 【一起学数据结构与算法分析】第二篇:字谜游戏
  14. JAVA适配器特点_适配器模式的优缺点
  15. 《Two-Archive Evolutionary Algorithm for Constrained Multiobjective Optimization》阅读笔记
  16. nofollow是什么意思,nofollow标签的作用是什么?
  17. TypeScript 类型声明文件.d.ts
  18. (R语言)R的统计模型
  19. 当前京东数据平台用到spark 的五种方式
  20. appium Original error: Could not proxy command to the remote server. Original error: socket hang up

热门文章

  1. 职高计算机自我鉴定800字,中专生自我鉴定800字与中专生计算机专业自我鉴定汇编...
  2. c语言中函数可以有几个参数,C中子函数最多有几个形参
  3. php mariadb 查询语法,从PHP调用的查询中的MySQL(MariaDB)执行超时
  4. UE4学习-设置地图,创建材质
  5. 在linux运行math_neon库,linux - 仅使用带交叉编译器的本地库 - 堆栈内存溢出
  6. Linux用于账号文件,linux的文件及账号管理
  7. mongodb存list_查询 MongoDB 子文档的 List 字段
  8. 基于matlab的状态反馈与极点配置
  9. webpack多个Html,少量修改webpack配置支持打包多页面
  10. java面向对象程序设计(jdk1.6)第三版 目录页数_Java面向对象程序设计/普通高等教育计算机规划教材简介,目录书摘...