一、TCP/IP模型

应用层Application:HTTP,HTTPs,FTP,DNS…
传输层Transport:TCP,UDP
网络层:Internet:IPv4,IPv6
网络访问层Network Access:以太网络、Wi-Fi

二、TCP
TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义

三、Linux TCP的实现
接收数据

- 首先linux中用sk_buff数据结构描述packet
- NIC( network interface cards) 即网卡检测到有packet到达,从Kernel Memory分配sk_buff数据结构,调用DMA(Direct memory access) Engine(注:DMA允许特定硬件直接操作主存。)将包放到sk_buff里面。NIC检测packet到达和packet的发送,不是触发,都是通过poll轮询的方式完成
- Ring Buffer将数据包放置到内核内存区,Ring Buffer的大小固定,不包含实际的数据包,仅包含了指向sk_buff的描述符。当Ring Buffer满时,新来的数据包会被丢弃。
- 一旦数据包被成功接收,NIC发起中断,内核的中断处理程序会将数据包传递给IP层,经过IP层的处理,数据包会被放入队列等待TCP层处理。每个数据包经过TCP层的一系列复杂步骤,更新TCP 状态机等等。
- 最终到达recv Buffer。TCP层返回ACK确认。用户空间则调用系统调用read(), 读取相应的报文内容。
- recv Buffer的大小可以通过修改
/proc/sys/net/ipv4/tcp_rmem来修改,cat /proc/sys/net/ipv4/tcp_rmem返回三个值,依次为最小,默认,最大
发送数据

TCP发送报文和接收报文路径相反,数据包的发送从上至下也经过了三层:用户态空间,系统内核空间,网卡驱动。
- 应用先将数据写入TCP send Buffer。
- TCP层将send Buffer中的数据构建成TCP 数据包转给IP层
- IP层会将TCP数据包进行处理,并放入QDist(queueing discipline)队列。数据包放入QDist之后,指向数据包的描述符sk_buff被放入Ring Buffer,随后网卡驱动调用DMA Engine将数据包发送到网络链路上。
四、网络参数调优
backlog
syn queue:tcp_max_syn_backlog
accept queue

- somaxconn
sysctl -w net.core.somaxconn=32768
sysctl -w net.ipv4.tcp_max_syn_backlog=16384
sysctl -w net.core.netdev_max_backlog=16384
tcp_syncookies
tcp_mem
tcp_rmem
tcp_wmem
sysctl -w net.core.rmem_default=262144
sysctl -w net.core.wmem_default=262144
sysctl -w net.core.rmem_max=16777216
sysctl -w net.core.wmem_max=16777216
sysctl -w net.core.optmem_max=16777216
#sysctl -w net.ipv4.tcp_mem='16777216 16777216 16777216'
sysctl -w net.ipv4.tcp_rmem='1024 4096 16777216'
sysctl -w net.ipv4.tcp_wmem='1024 4096 16777216'
- fs_nr_open
六、FAQ
backlog、半连接队列、全连接队列是什么?
TCP根据什么定义一个连接
TCP怎么保证可靠
TCP怎么解决乱序问题
TCP拥塞控制
Socket缓冲区满了会怎样
TCP缓冲区和滑动窗口之间的联系
参考文档
https://coolshell.cn/articles/11609.html
https://jishuin.proginn.com/p/763bfbd6646f
Linux TCP队列相关参数的总结_阿里云基础设施_新浪博客
https://sn0rt.github.io/media/paper/TCPlinux.pdf