send函数的流程:
buffer的内容 —->linuxTCP协议栈发送缓存区—->内核发送
什么情况下,buffer内容才会先写入协议缓存区呢 ,协议缓存区有一个SO_SNDLOWAT最低位标志,表示缓存区有空间了, 一般是2048字节。就是说缓存区至少2048字节剩余空间,你才能继续向缓存区写。selcet /epoll等监视内核,就是依据这个,判断socket是否可以向缓存区写数据,就是产生可写事件。
recv函数的流程:
内核接受远端数据—–>存到linux TCP协议接收缓存区—–>copy到buffer里面(同时要清除协议缓存区)
什么情况下可以读取数据呢, 协议缓存区有一个SO_RCVLOWAT 最低水位标志,表示缓存区有数据了,你可以读取了,这个值是1字节。如果你给的buffer一次性读取不完,就要循环读取,直到读取返回EAGAIN,就表示读完了,返回0表示socket已关闭。所以读取一般是while循环。select/epoll 等就是靠内核监视,这个协议缓冲区有没有数据,产生是否有了可读事件。