TCP/IP详解第18章-TCP连接的建立与终止 摘录
引言
TCP面向连接,连接前需要需要经历握手接阶段
连接的建立与终止
- tcpdump的输出,观察S、F、R、P四个标志、包序号、窗口大小、mss最大报文段长度
- 三次握手建立连接,能够画出状态图,分析握手时如果出现丢包该怎样
- 四次挥手终止连接,能够画出状态图,分析挥手时如果出现丢包该怎样
连接建立的超时
- SYN超时,观察第一次超时时间,引申出TCP的500ms定时器
- 服务类型字段TOS,暂时不知道什么含义
最大报文段长度
SYN中携带MSS表示传给另一端的最大报文断长度(对方收到后,发送的报文段长度不能超过此值, 也就是限制了对方发送报段的长度),MSS值是外出接口上MTU长度减去 固定的IP首部和TCP首部长度,对于以太网,MSS值为1460字节。
如果两台主机不在同一个网络,但中间网络采用较低的MUT例如295,每台主机的直接外出接口都比295大, 则数据经历中间网络,仍会进行分段。
TCP半关闭
连接的双发,只有一方关闭发通道,仍能进行接收;对端不关闭,能具备发送的能力。
TCP状态变迁图
2MSL等待时间
TIME_WAIT状态称为2MSL等待时间,每个具体TCP实现必须选择额一个报文段最大生存时间MSL。 是任何报文段被丢弃前在网络内的最长时间。
了解为什么主动关闭放最后阶段要等待2MSL。
正常情况下,在2MSL阶段,当前连接对(localip:localport, remoteip:remoteport)不能被使用, 在具体是实现上更为严格,单独的localport都不能被使用,但可通过tcp的SO_REUSEADDR选项来使本地端口可用。 尽管通过tcp的SO_REUSEADDR选项可以重用localport了,但相同的连接对(localip:localport, remoteip:remoteport)原则上 在此阶段是不能使用的。
例子: A主机 服务器 6666端口 B主机 客户端 1098端口 A主机服务器主动关闭后,A主机服务器连接处于TIME_WAIT阶段,此时:
- 在A主机上,以6666端口启动服务器或客户端,报错端口在使用中;
使用SO_REUSEADDR选项后,以6666端口启动客户端且连到B主机IP的1098端口,仍会报错, 因为此连接对仍处于TIME_WAIT状态。 - 在B主机上,以1098重启客户端且连到A主机6666端口,会成功,最然违反了规定。
它要求只要新的连接比上次最后一个序号大就行。
但如果在此TIME_WAIT状态,B主机以为
2MSL内,任何迟到的报文段将被丢弃(只响应重传的ack?)
平静时间概念
使用2MSL时间断,可以使得该连接的所有报文在此期间都在网络消亡,防止迟到的报文被解释成后续新连接的一部分。 使用2MSL等待端口的主机出现故障,它会在MSL秒内重启,并立即使用故障前处于2MSL的插口来建立一个新连接。 如果是这样,在故障前从这个连接发出而迟到的报文会被错误地当作重启后新连接的报文段。 为了防止这种情况,TCP在重启后的MSL内不能建立任何连接。
FIN_WAIT_2状态
主动关闭方发出FIN后,收到对方的ack进入FIN_WAIT_2状态,但如果对方不执行关闭,则自己一直处于此状态。 例如服务器由于某些原因主动关闭,但客户端不回复第三次握手,则消耗服务器资源。
一般设置一个定时器,或者服务器关闭时采用no_linger直接发RST关闭。 (发RST包时不必等缓冲区包都发出去,直接丢弃缓冲区包发送RST包; 而接收方收到RST后也不必发送ACK进行确认)
复位报文段
无论何时一个报文端发往referenced connection出现错误,tcp发出一个复位报文段。
- 到不存在的端口的连接请求
产生ICMP端口不可达信息,TCP返回复位 - 异常终止一个连接
不使用FIN正常关闭,直接回复RST,丢失发送缓存中所有数据 - 检测半连接打开
一方已经关闭或异常终止连接而另一方不知道,称这种tcp为半打开half-open。 只要不打算在半打开的连接上传输数据,仍处于连接状态的一方就不会检测到另一方已出现异常。
同时打开
两个应用程序同时执行主动打开,发生可能性极小。(只要了解)
同时关闭
同时关闭,仍是四次握手。
TCP选项
kind字段
TCP服务器的设计
服务器端口号
根据netstat -ant查看处于LISTEN状态的tcp连接,其中Local Address和Foreign Address有多种 形式,如:::8080 和::😗,表示监听在服务器任意接口上的8080端口,可以接受任何远端连接。 当建立连接后,处于LISTEN状态的服务器进程仍然存在,该进程是当前服务器用于接收其他的连接请求。当传入的连接请求到达并被接收时,系统内核中的TCP模块就创建一个处于ESTABLISHED状态的进程。只有处于LISTEN状态的进程能够接收新的连接请求,处于ESTABLISHED的进程不能接收SYN报文段,而处于LISTEN的进程不能接收数据报文段。
限定本地IP地址
服务器Bind时指定ip地址,则在netstat中观察到的Local Address显示绑定的ip地址
限定远端IP地址
UDP服务器再指定IP本地地址和本地端口外,还能指定远端IP地址和远端IP端口。 但大多数API不支持这么做,服务器必须不知名远端端口,而等待连接请求到来后,再检查客户端的IP地址和端口号。
呼入请求队列
正等待连接请求的一端有一个固定长长度的连接队列,三次握手已完成的连接被放入其中。 队列的最大长度成为backlog,一般为5,它表示已经TCP接收而等待应用层接收的最大连接数。 如果队列有空间,SYN连接时进行确认并完成连接确立。 如果没有空间,SYN连接将不被响应,不发送任和报文,客户端将会超时。
|