TCP连接的建立和终止
TCP数据包格式:
TCP数据包中没有标识数据大小的字段,这个字段定义在IP首部中了。
TCP首部长度最小是20字节,最大是60字节,首部长度就定了偏移量,标识了TCP首部的大小
TCP流量控制是由连接的每一端通过声明 窗口大小来提供的,这个值是16比特,所以最大是65535字节。
校验和覆盖了整个TCP报文段,首部和数据,这是一个强制性的字段,一定是由发送端计算和存储,并由接收端进行验证。
只有当URG标志设置为1时紧急指针才有效。紧急指针是一个正的偏移量,和序号字段中的值相加表示紧急数据最后一个字节的序号。
最常见的可选字段是 最长报文大小,又称为 MSS(Maximun Segment Size)。每个连接方通常都在通信的第一个报文段(SYN包)中指明这个选项,它指明本端所能接收的最大长度的报文段。
比如A的MTU为296字节,也就是以太网可以发送的包的最大大小,而B的MUT是1500字节,那么当双方建立连接时,A发送的SYN包就指明了MSS为256(296-40),而B的SYN包中指明了MSS为1460(1500-40)。此时使用较小一方的MSS,也就是256字节作为数据报文长度。
MSS默认值为536字节
TCP中的六个标识比特,他们中的多个可以同时被设置为1,含义如下
标志比特 | 含义 |
CWR | 流量控制 |
ECN | 拥塞窗口 |
URG | 紧急指针有效 |
ACK | 确认序号有效 |
PSH |
接收方应尽快将这个 报文段交给应用层 |
RST | 重建连接 |
SYN |
同步序号用来发起一个 连接 |
FIN |
发端完成发送任务 |
TCP的状态变迁图
TCP连接的建立,数据传输,以及关闭的过程
状态转换和连接建立关闭的对比图
分成三部分
1.连接的建立过程
2.数据的传输过程
3.连接的关闭过程
连接过程(三次握手)
这是由一个主动,一个被动的过程,客户端主动触发一个连接,服务端接收连接,最初客户端和服务端都处于 CLOSED状态。
对于客户端来说,首先会发送一个SYN包,之后TCP状态就变为 SYN_SENT,而当客户端收到服务端发来的ack+syn包时,对于客户端来说他已经确定了服务端收到了之前发送的SYN包了,所以客户端的TCP状态就变成了 ESTABLISHED.
对于服务端来说,当调用listen()函数之后,就看以监听客户端的发来的SYN包了,当收到SYN包之后,服务端的TCP状态就变为 TCP_RCVD,同时客户端还会向服务端发送一个syn+ack包,也就是服务端也要创建连接。最后当客户度收到这个syn+ack包后,最后会再发一个ack包给服务端,也就是TCP状态转换图中SYN-SEND状态指向 SYN-RECEVED状态的箭头,也就是客户度最后的确认ack,当服务端收到这个ack后,连接就建立了,这样服务端的TCP状态也变为 ESTABLISHED.
数据传输过程
只有一种状态 ESTABLISHED
关闭过程
这里分为主动关闭和被动关闭,还有双方同时关闭。
客户端发送fin包后,TCP状态就处于 FIN_WAIT_1,如果收到服务端发来的ack确认后,状态就变为 FIN_WAIT_2。之后客户端会等待服务端发送fin包,也就是等待服务端关闭。当收到服务端发来的fin包后,客户端会发送一个确认,此时客户端的状态就变为 TIME_WAIT,等待2ML时间后,状态就变为了 CLOSED。
对于服务端来说,收到客户端发来的fin包后,状态就变为 CLOSE_WAIT,也就是被动关闭,同时会发送一个ack确认给客户端。之后服务端也会发送一个fin包给客户端,表示关闭连接,之后状态就变成了LAST_ACK,此时服务端会等客户端发送最后一个确认ack,当收到后服务端就会关闭连接,状态就变为 CLOSED。
同时关闭是双方都是主动关闭,双方都发送了一个fin包。客户端主动关闭发送fin包后,变成 FIN_WAIT_1状态,此时又收到了一个fin包,于是状态变为 CLOSING,同时再发送一个确认包ack给对方。而当收到对方对fin包的确认后,状态变成了 TIME_WAIT,等待2ML时间后,连接关闭,变为 CLOSED状态,对于服务端来说情况是一样的就不在阐述了。
同时关闭的状态图
通过Wireshark抓包分析连接的建立和关闭过程
表达式为:
(ip.dst_host==61.135.169.105 and ip.src_host==192.168.0.100) or (ip.dst_host==192.168.0.100 and ip.src_host==61.135.169.105)
详细看一下连接的建立过程,首先是客户端发送一个SYN包
此时的只有一个序列号,没有确认序列号,序列号是3285497608
另外在可选项中有一个MSS,设置为1460,还有一个SACK。
服务端收到SYN包后,发送SYN+ACK包
此时服务端的序列号是3447498448,同时对客户端的序列号进行了确认,也就是序列号+1,所以ack是3285497609
服务端的MSS设置为1440,所以使用两者中较小的一个MSS,也就是1440字节。
最后客户端回一个ack包给服务端
应答的ack是服务端序列号+1,所以ACK就是3447498449
双方关闭连接的四次握手TCP包都没有数据,包头都是20字节,通过Wireshark的抓图就能看出来,这里就不再描述了。
参考:
已有 0 人发表留言,猛击->> 这里<<-参与讨论
ITeye推荐