send函数和recv函数

send函数和recv函数

write()/read() 与 send()/recv() 的区别

  • 由于两组函数的都能通过文件描述符收发网络数据,所以两组函数在功能上有一定的重叠;
  • 但是,send/recv函数在数据收发上功能更专业更齐全;

函数原型

  • 头文件包含:#include <sys/socket.h>
  • 函数原型:
ssize_t  send(int sockfd,const void * buf, size_t nbytes, int flags);
ssize_t  recv(int sockfd,void * buf, size_t nbytes, int flags);
  • flags:收发数据时指定的可选信息;
    当flags为0时, send等待发送缓冲区清空后把数据放入缓冲区再返回(有可能等待),recv等待数据缓冲区有数据后获取再返回(有可能等等待);
    当flags为0时, send()/recv() 在功能上等价于 write()/read() ;
  • flags可选配置:
可选项含义sendrecv
MSG_OOB用于传输带外数据(Out Of Band data),即:紧急数据
MSG_PEEK窥探接收缓冲区是否存在数据
MSG_DONTROUTE数据传输过程不通过路由,在本地局域网中寻找目的地
MSG_DONTWAIT非阻塞模式,数据收发时立即返回
MSG_WAITALL在接收到请求的全部数据之前,不提前返回
MSG_MORE有更多数据需要发送,指示内核等待数据

注意:不同操作系统对可选项的支持不同,实际工程开发时,需要事先对目标系统中支持的可选项进行调研

MSG_OOB(带外数据/紧急数据)

  • 原生定义:
    – 使用与普通数据不同的通道独立传输数据;
    – 带外数据优先级比普通数据高(优先传输,对端优先接收);
  • TCP中的带外数据:
    – 由于原生设计的限制,TCP无法提供真正意义上的带外数据
    – TCP中仅能通过传输协议消息头中的标记传输紧急数据,且长度仅1字节
  • TCP带外数据实现的原理:
URGURG指针0x010x02带外数据URG指针指向的位置

URG指针指向紧急消息的下一个位置,即:URG指针指向位置的前一个字节存粗了紧急数据;
紧急数据会放在有别于普通数据的特殊数据缓冲区;

  • TCP带外数据的处理策略:
    – 由于TCP设计为流式数据,因此,无法做到真正的带外数据;
    – 被标记的紧急数据可被提前接收,进入特殊缓冲区(仅1个字节);
    · 每个TCP包最多只有一个紧急数据
    · 特殊缓冲区仅存放最近的紧急数据(不及时接收将丢失)
  • 使用select接收紧急数据
    – socket上收到普通数据和紧急数据时都会使得select立即返回(通过FD_ISSET监测 select返回的exceptset参数来判断是否是紧急数据);
    · 普通数据:socket处于数据可读状态(可读取普通数据);
    · 紧急数据:socket处于处理异常状态(可读取紧急数据);
  • 总结:
    read/write函数可用于收发普通数据(不具备扩展功能)
    send/recv可通过选项信息扩展更多功能
    TCP紧急数据可标识256(1个字节,2^8)种紧急事件(异常事件)
    通过select能够及时处理紧急数据并区分普通数据

MSG_PEEK(数据窥探)

  • recv()专用选项,可用于数据预接收;
  • 指定MSG_PEEK选项时,不会清空缓冲区;
  • 可用于获取接收缓冲区中的数据量(字节数);

MSG_DONTWAIT(立即收发模式)

  • 数据收发时不阻塞,立即返回;
  • send() :如果无法将数据送入发送缓冲区,那么直接错误返回;
  • recv() :如果接收缓冲区中没有数据,那么直接错误返回;
  • send()/recv()返回值:-1:错误发生,0:对端调用close()关闭连接,n:发送/接收的数据量

阻塞发送模式(flags: 0)

  • send():
    发送数据长度 > 发送缓冲区长度 : 返回错误
    发送数据长度 <= 发送缓冲区剩余长度复制数据到发送缓冲区
    发送缓冲区剩余长度<发送数据长度<=发送缓冲区长度等待发送缓冲区清空
  • recv():
    接收缓冲区中没有数据时等待数据
    接收缓冲区数据量 <= 接收区长度数据全部拷贝到接收区
    接收缓冲区数据量 > 接收区长度拷贝部分数据到接收区

MSG_WAITALL(等待数据)

  • 接收专用,等待需要的数据量完全满足时,recv()才返回

MSG_MORE(更多数据)

  • 发送专用,指示内核不要着急将发送缓冲区中的数据进行传输
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值