TCP网络编程处理的三个半事件

TCP网络编程最本质的是处理三个半事件:

  1. 连接建立:包括服务器端被动接受连接(accept)和客户端主动发起连接(connect)。TCP连接一旦建立,客户端和服务端就是平等的,可以各自收发数据。
  2. 连接断开:包括主动断开(closeshutdown)和被动断开(read()返回0)。
  3. 消息到达:文件描述符可读。这是最为重要的一个事件,对它的处理方式决定了网络编程的风格(阻塞还是非阻塞,如何处理分包,应用层的缓冲如何设计等等)。
  4. 消息发送完毕:这算半个。对于低流量的服务,可不必关心这个事件;另外,这里的“发送完毕”是指数据写入操作系统缓冲区(内核缓冲区),将由TCP协议栈负责数据的发送与重传,不代表对方已经接收到数据。

 

下面我们重点讨论一下消息到达消息发送完毕事件:

消息到达事件 

socket有数据到来时,数据先被内核接收,存放在内核接收缓冲区中,网络库事件循环中的可读事件被触发,将数据从内核缓冲区移动到应用缓冲区中,并且网络库会回调一个OnMessage函数表示有消息到达。

由于TCP接收到的可能是半包(即数据不完整),OnMessage要根据协议来判断这个数据包是否完整。

而如果TCP接收到的数据包是完整的,就直接将这个数据包取出来进行处理(read->decode->compute->encode->write);而如果TCP接收到的数据包不完整,则OnMessage立即返回,这样内核再接收到一些数据时,网络库事件循环中的可读事件又会被触发...直到OnMessage发现数据包已经完整了,才它取出来进行处理(read->decode->compute->encode->write)。

消息发送完毕事件

假设现在应用层要发送数据,如果内核发送缓冲区足够大,则将要发送的数据全部填入内核缓冲区中,并触发一个发送完成事件,并且网络库会回调一个OnWriteComplete函数表示消息发送完毕;而如果内核发送缓冲区不足以容纳这么多的数据,则只将其中一部分数据填入内核缓冲区,剩余部分追加到应用层的发送缓冲区中,等内核发送缓冲区将数据发送出去后,会触发一个可写事件,在这个事件中就会将应用层发送缓冲区中的数据填充到内核发送缓冲区中,这时如果内核发送缓冲区不足以容纳应用层发送缓冲区中的全部数据,则只将其中一部分数据填入内核缓冲区...就这样直到应用层发送缓冲区中的数据全部填充到内核缓冲区,网络库事件循环中的发送完成事件会被触发,并回调OnWriteComplete表示消息发送完毕。

注意:应用层一定要在应用层发送缓冲区中的数据全部填入内核缓冲区并回调OnWriteComplete表示消息发送完毕后才能继续发送数据,这样做可以避免数据丢包。

 

编程示例:6.4.2 echo服务的实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值