Linux入门真经-047TCP会话的建立与断开

xiaoxiao2022-05-13  27

 

敲!黑!板!无论是大学计算机网络期末考试,还是网络/运维/技术支持乃至程序猿面试,这个问题都命中率极高。本篇文章会介绍TCP连接的建立与断开以及一些常用的TCP参数,不过,仅限于入门知识哈。

 

1、TCP头中的重要参数

 

seq与len:

 

TCP的传输是有序的,它为每一个数据段都标上了一个序号。因为传输距离的遥远和网络的庞大和复杂,先发出去的包未必就能先到达目的地,因此数据段乱序时有发生,甚至某些数据会在传输过程中丢失。有了序号,目的端可以根据序号进行排序,当发现中间缺少部分数据的时候,只需要请求发送端重传这一小段数据就可以了。

seq就表示了数据段的序号,而len表明了数据段的长度。比如我们发送了一个数据段,seq=1,len=1448,如果后面还有数据,那么第二个包的seq应当是1+1448=1449,也就是说,下一个数据段的seq号等于上一个数据段的seq+len。你可以比照一下下图

TCP是双向的。在一个连接中,双方都可以是发送方。因此各自维护了一组seq号码。

另外补充一点,len的长度是可以为0的,len不包括TCP头的长度,很多维护会话性质的数据段的len就是0,而TCP的头部其实包含了很多信息。

ack:确认号。它告诉发送方已经收到了一些信息,并希望发送方下一次发送哪些字节。ack号的数值就是期望下一次发送方发送数据段的seq值。

比如甲和乙建立了TCP连接后,甲发送了一个数据段的seq=x,len=y;那么乙回复的时候ack=x+y,表示它收到了x+y之前的所有字节,并期望甲发送seq=x+y的数据段。

 

同理,由于tcp连接的两端都能是发送方,因此他们各自维护自己的ack号。

 

试图理解下面这个例子以确认你理解了seq、len、和ack这三个参数。

 

甲和乙建立起了TCP连接。乙依次收到了下面几个数据包,seq和len的值分别是:

seq=1000,len=100

seq=500,len=100

seq=600,len=100

 

乙根据seq排序之后顺序如下:

seq=500,len=100

seq=600,len=100

seq=1000,len=100

 

排序完成后,发现seq=600,len=100之后后面收到的seq=1000,判断中间少了些什么数据,所以它回复了一个数据包,tcp头部中的ack=700,希望甲可以重传seq=700的包。

 

好的,接下来我们再来看几个关于建立和断开连接的参数:SYN、FIN、RST

 

这几个位,包括刚刚介绍的ACK,都位于TCP的FLAG字段中,有着不同的含义,比如,ACK位置1则表示这个数据段包含了ACK信息。

当然,FLAG字段中还有一些其他的位,表示了不同的含义,接下来介绍常见的SYN、FIN、和RST

SYN:携带这个标志位表示希望能够发起一个TCP连接请求,有点像打电话的时候,双方都会先说一句:“喂”。

FIN:表示有一方希望能够正常地终止请求。

RST:用于重置连接,或者拒绝请求。

 

端口

TCP通信借助于计算机的端口。接入网络的计算机往往会同时有几十上百个TCP连接,不同的应用层协议会监听在不同的端口之上,计算机根据所收到数据段的目的端口,将数据传送给不同的应用层协议处理。发送TCP数据的时候要指明目的端口在哪里,目的主机才知道把数据给哪个应用程序;同时TCP头中也会包含源端口,方便接收端回复数据时,回复的数据能够抵达发送端对应的应用程序。

比如下面这个数据段,源端口就是发送端主机的44208端口,目的端口就是接收端的54321端口

 

下面附上一个TCP头部结构图,你可以参考比照上面wireshark中TCP字段的结构内容。

 

2、三次握手与四次挥手

 

好的,让我们来了解一下TCP会话的建立过程

 

建立连接时,一定是某一方先发起请求,假设发起请求的是client端(事实上也通常如此),client先发送一个SYN置1的包,表示想要建立连接。发送完毕后client端就处于SYN_SENT状态;

 

server在收到SYN包之前处于listen状态,监听在某一端口等待连接的到来;

 

server收到后SYN包,发送ack表示收到了这个包,同时在数据段中将SYN位也置1。发送后server处于SYN_RCVD状态。

 

当client收到server发出的这个包之后,会发送ack表示自己收到了这个包,client将自己置为ESTABLISHED状态,此时三次握手完成,开始传输数据。

 

三次握手过程如下图

 

如下图就是一个三次握手的报文示例,它是TCP会话的开端,如下图,完成会话后,客户端就向服务器提出了GET / HTTP/1.1的请求,然后服务器开始向客户端传输数据。

一次TCP会话可以传输多个资源,比如本次客户端请求/ HTTP/1.1的资源之后,它还能够请求/_static/jquery.js HTTP/1.1\r\n;或者图片、动画等资源,都能在本次TCP会话中进行传输。

 

TCP四次挥手

 

天下没有不散的宴席,TCP会话有建立就有终止。

 

仍然借用之前的例子,假设client现在要终止会话。(任何一端都可以终止会话)

client发送一个FIN置1的数据段表明自己要断开连接。发送完毕后自己则处于FIN_WAIT_1状态

server收到这个包之后,将自己置于CLOSE_WAIT状态,接着他会向client发送两个包,一个是ack包,声明刚刚那个包自己已经收到,一个是FIN包,因为TCP连接是双向的,己方也要请求中断连接。发完这两个包之后server端处于LAST_ACK状态。

client收到server发来的FIN包之后,发送ack包表示已经收到,将自己置于TIME-WAIT状态,等待一段时间后关闭会话。

Server收到client发来的ack包之后,关闭会话。

 

整个过程整理如下图。

 

并不是所有的TCP会话都会正常地结束,有时会使用RST标志来终止会话。收到RST置1的数据包之后,不会有任何的后续,连接直接关闭。导致RST的原因有很多,客户端关闭、服务端拒绝连接、防止恶意扫描、软件崩溃等等都可能导致RST的发生。

比如下面这个示例,客户端发送FIN,ACK请求终止连接,重传了数次仍然没有收到任何回应,最后客户端用RST重置了连接。

 

3、一些拓展性问题

 

TCP协议是一个经久不衰的话题。会话的建立和断开只是和TCP相关的一个很小的知识点。还有很多有意思、有深度的周边话题值得你去了解。你还可以深入地了解一下TCP的重传机制、延迟确认机制、滑动窗口机制、慢启动、拥塞避免方法等。这些东西对新手并不友好,而且一些细节很容易遗忘。但是了解这些内容很有必要,建议做好笔记,让自己有个印象。这样遇到一些故障或者性能问题时,你可能会更有头绪。

 

下一章为大家解释跨网段通信是如何进行的,以及NAT地址转换技术。下下章为大家介绍IPV6协议,它的出现旨在解决IPV4地址不够的问题。再接下来我们会回到Linux系统,介绍一系列关于网络的命令与参数。

关注本公众号获取最新更新(公众号名:linux入门真经)

每周一、三、五稳定更新

转载请注明原文地址: https://www.6miu.com/read-4884172.html

最新回复(0)