网络编程(8): 如何正确的收发数据(基于IO多路复用)

在IO多路复用下,服务器通过IO复用函数监听clientfd的读事件以接收数据,可能需多次recv完成。发送数据时通常不注册可写事件,除非遇到EWOULDBLOCK。epoll中,水平模式读事件触发后持续触发,需管理事件注册;边缘模式下,读事件触发需一次性收完数据,写事件仅在不可写到可写时触发。
摘要由CSDN通过智能技术生成

如何正确的收发数据(基于IO多路复用)

前置

  • 非IO多路复用,这种情况一般都是一个连接一个进程/线程,对应的IO模型是IO阻塞、IO非组模型,是在一个进程/线程里面完成数据的收发,整个流程是利用同步IO完成的同步编程(同步的进行收发即可)。
  • 基于IO多路复用,需要配合IO复用函数来判断socket的可读可写事件。

如何正确的收数据(对于服务器)

  • 与客户端建立连接得到clientfd,将clientfd绑定到对应的IO复用函数上,监听clientfd的读事件,读事件触发,就利用recv读取数据, 数据可能一次收完, 或者多次收取.
  • 对于epoll的水平模式, 可以每次只收取一部分, 对于边缘模式, 必须通过while循环全部收完, 通过recv返回-1 ,errno是EWOULDBLOCK.

如何正确的发数据

  • 对于发数据, 除了epoll的边缘模式外, 通常不会去注册可写事件, 因为大多数情况下, socket都是可写的, 水平模式会导致IO复用函数一直触发.
  • 一般都是先send直接发送, 当如果发送过程中 返回-1, 且errno是EWOULDBLOCK表示TCP窗口太小数据无法写入, 这个时候还有数据没法出去, 就需要注册可写事件, 当数据发完了, 需要取消可写事件.

epoll 的边缘和水平模式的数据收发

  • 水平模式:
    • 收数据: 一般是先注册读事件, 读事件触发, 进行收数据, 只需要注册一次, 只要缓冲区有数据就会一直触发, 且可以进行任意的收取数据, 当连接关闭的时候, 需要取消挂载.
    • 发数据: 一般是先发数据, 如果由于TCP窗口太小导致数据没法完, 需要注册可写事件, 如果数据一直没发完, 也不需要重复注册可写事件, 等待触发就可以了, 当数据发完了, 需要取消注册的可写事件, 一般不是网络出问题, socket一直都是可写的, 为了避免当没数据要发的时候一直触发水平模型的情况, 就需要取消可写事件.
  • 边缘模式:
    • 收数据: 注册可读事件, 当缓存区有数据需要while循环直到收完, 不然缓存区残留数据,边缘模式下次不会触发.
    • 发数据: 可以一开始就注册可写事件, 然后去发数据, TCP窗口太小, 导致数据没发完, 数据能发的时候, 注册的可写事件会触发让你去发数据, 所以只需要注册一次可写事件, 不要取消可写事件的注册. 但是如果正常情况下, socket是一直可写的, 那数据发完, 还想监听可写事件, 需要重新注册可写事件, 不然不会触发, 也就是说, 边缘模式的可写, 只有socket从不可写到可写才会触发.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值