一、概述
TCP是面向连接、可靠的、基于字节流的传输层通讯协议。
如何确定一个TCP连接:
- 目的IP
- 目的端口
- 源IP
- 源端口
二、TCP建立连接
序列号client_isn和server_isn是随机初始化,可以通过netstat -napt来查看网络状态。
为什么建立连接需要三次握手?
- 防止历史重复连接初始化。
- 同步双方初始序列号。
- 有效的避免资源浪费。
为什么初始的序列号是随机的?
网络中情况是不确定的、会延迟、也有可能复制重发,为了防止不同连接之间的报文混乱,所以需要随机产生。
什么是SYN攻击?如何避免SYN攻击?
TCP三次握手在服务端分为半连接队列和全连接队列。
攻击者短时间伪造大量的IP地址和端口在短时间内对服务端发起连接,会沾满SYN队列,导致无法为正常用户服务。
- 修改内核参数,增大队列容量,将超出的SYN请求丢弃。
- 开启cookie,net.ipv4.tcp_syncookies = 1,当SYN队列满了时,收到SYN请求,计算出一个cookie值,和SYN+ACK一块返回给客户端,到第三次握手时再发过来,服务端判断cookie的合法正确性,如果合法则放到accept队列中,否则丢弃。
三、TCP断开连接
为何TIME_WAIT需要2MLS?
MLS(MaximunSegement Lifetime),网络中可能还有剩余没有到达的数据报,收到后确认正好2MLS。
为何需要TIME_WAIT状态?
- 防止收到旧的相同四元组的数据。
- 保证被动连接一方正常关闭,即最后那个ACK可已被接收。
TIME_WAIT过多有何危害?
- 浪费内存资源。
- 占用TCP连接端口。
如何优化TIME_WAIT状态?
- 打开net.ipv4.tcp_tw_reuse和net.ipv4.tcp_timestamps(TCP时间戳,复用的数据包可根据时间戳来判断是否过期)。使得处于TIME_WAIT状态的端口可以被重新使用。
- net.ipv4.tcp_max_tw_buckets(默认18000,超过此值,所有TIME_WAIT连接重置,不推荐)。
- 程序中使用 SO_LINGER,调用close后发送RST,不提倡。
连接时,客户端出现故障怎么办?
保活机制。
四、Socket编程
listen 时候参数 backlog 的意义?
设置accep连接队列的长度。
connect和accept发生在那步?
客户端connect成功在三次握手的第二步,服务端accept成功发生在第三步。