调用数据发送接口以后
- 调用write或者send这些系统调用,数据只是从应用程序拷贝到了系统内核的套接字缓冲区中,接下来要通过操作系统内核的TCP协议栈来进程数据传输。
- 系统内核套接字缓冲区的数据结构:
流量控制
相当于一个生产者-消费者模型,两者的效率要适配
拥塞避免
TCP数据报要经过网卡、交换机、核心路由等一系列的网络设备,则TCP要考虑多个连接共享在有限的带宽上的效率和公平性。
应对小数据的发送
场景一:在发送方进行优化
场景:发送端只发送很小的数据,但是也需要经过一系列的TCP连接的过程,耗费大量的资源来发送一点数据,不是很值。
解决思路:Nagle算法
本质是限制大批量的小数包报同时发送。(这里的小数据包是指长度小于最大报文段长度MSS的TCP分组)
为此,它提出,在任何时刻,未被确认的数据报不能超过一个。
这样,发送端就可以把接下来连续的几个小数据包存储起来,等待接收到前一个小数据包的ACK分组后,再一次性把数据发送出去。
补:nagle算法不太使用对时延性要求高的场景
场景二:在接收方进行优化
场景:接收端发送大量的ACK确认报文,会消耗大量的带宽。
解决思路:延时ACK
收到数据后不马上回复,而是累计需要发送的ACK报文,等到有数据需要发送给对端,则把累计的ACK捎带一起发送出去。
补充
对于小数据,也可以将写操作合并(称为集中写):
在写数据之前,将数据合并到缓冲区,批量发送出去。
需要用writev()系统调用函数