TCP连接的建立和终止

标签: tcp | 发表时间:2014-06-01 21:46 | 作者:我是小小鸟
出处:http://www.iteye.com

 

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的抓图就能看出来,这里就不再描述了。 

 

 

参考:

TCP的那些事儿

TCP协议中Window Scale Option问题

TCP/IP ECN分析

Congestion window

TCP协议

 



已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [tcp] 推荐:

tcp/ip调优

- Lucseeker - 在路上
在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接. 第一次握手:建立连接时,客户端发送syn包(syn=x)到服务器,并进入SYN_SEND状态,等待服务器确认;. 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(syn=y),即SYN+ACK包,此时服务器进入SYN_RECV状态;.

浅谈TCP优化

- - 火丁笔记
很多人常常对 TCP优化有一种雾里看花的感觉,实际上只要理解了TCP的运行方式就能掀开它的神秘面纱. Ilya Grigorik 在「 High Performance Browser Networking」中做了很多细致的描述,让人读起来醍醐灌顶,我大概总结了一下,以期更加通俗易懂. 传输数据的时候,如果发送方传输的数据量超过了接收方的处理能力,那么接收方会出现丢包.

TCP报文结构

- - 互联网 - ITeye博客
一、TCP报文结构如下:.  固定首部长度为20字节,可变部分0~40字节,各字段解释:. source port number:源端口,16bits,范围0~65525. target port number:目的端口,16bits,范围同上. sequence number:数据序号,32bits,TCP 连接中传送的数据流中的每一个字节都编上一个序号.

TCP 状态变化

- - 互联网 - ITeye博客
关闭socket分为主动关闭(Active closure)和被动关闭(Passive closure)两种情况. 前者是指有本地主机主动发起的关闭;而后者则是指本地主机检测到远程主机发起关闭之后,作出回应,从而关闭整个连接. 将关闭部分的状态转移摘出来,就得到了下图:. 通过图上,我们来分析,什么情况下,连接处于CLOSE_WAIT状态呢.

TCP/IP分享——链路层

- Goingmm - 弯曲评论
在张国荣自尽8周年纪念日,也就是愚人节的前几十分钟,终于把第二章弄完了. 首席似乎不是特别有空,我就斗胆在这里自己发了,从前面2期的反响来看,相当热烈,我也是摆出一副要杀要剐,悉听尊便的架势,这可能是受最近流行霸气外露的影响,批评几句又伤不了皮毛,也影响不了我的工作和正常生活,只要给大家带来快乐,我就很开心,似乎历史上很多想法都是在争吵中诞生的.

TFO(tcp fast open)简介

- chenqj - pagefault
原创文章,转载请注明: 转载自pagefault. 本文链接地址: TFO(tcp fast open)简介. 这个是google的几个人提交的一个rfc,是对tcp的一个增强,简而言之就是在3次握手的时候也用来交换数据. 这个东西google内部已经在使用了,不过内核的相关patch还没有开源出来,chrome也支持这个了(client的内核必须支持).

TCP/IP重传超时--RTO

- dennis - 一个故事@MySQL DBA
Shared by 子非鱼 安知余(褚霸). 概述:本文讨论主机在发送一个TCP数据包后,如果迟迟没有收到ACK,主机多久后会重传这个数据包. 主机从发出数据包到第一次TCP重传开始,RFC中这段时间间隔称为retransmission timeout,缩写做RTO. 本文会先看看RFC中如何定义RTO,然后看看Linux中如何实现.

TCP协议通讯流程

- - 操作系统 - ITeye博客
服务器调用socket()、bind()、listen()完成初始化后,调用accept()阻塞等待,处于监听端口的状态,客户端调用socket()初始化后,调用connect()发出SYN段并阻塞等待服务器应答,服务器应答一个SYN-ACK段,客户端收到后从connect()返回,同时应答一个ACK段,服务器收到后从accept()返回.

TCP短链接调优

- - 操作系统 - ITeye博客
最近在做一个项目,用到HttpClient查询数据,由于服务端强制做成了短链接(大家都知道http1.1默认是带有keepalive机制),导致了请求方TCP状态很多都是TIME_WAITZ状态,端口被全部占用,请求失败. net.ipv4.tcp_tw_reuse = 1 表示开启重用. 允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;.

TCP 的那些事儿(下)

- - 酷 壳 - CoolShell.cn
这篇文章是下篇,所以如果你对TCP不熟悉的话,还请你先看看上篇《 TCP的那些事儿(上)》 上篇中,我们介绍了TCP的协议头、状态机、数据重传中的东西. 但是TCP要解决一个很大的事,那就是要在一个网络根据不同的情况来动态调整自己的发包的速度,小则让自己的连接更稳定,大则让整个网络更稳定. 在你阅读下篇之前,你需要做好准备,本篇文章有好些算法和策略,可能会引发你的各种思考,让你的大脑分配很多内存和计算资源,所以,不适合在厕所中阅读.