TCP基础知识

来源:互联网 发布:淘宝转化率 编辑:程序博客网 时间:2024/05/16 07:24

参考自:http://www.jianshu.com/p/116ebf3034d9

一、TCP

关于TCP的具体,我这里就不细说,如这是我们每个程序员的基本知识,我这里就简单说下,看下OSI的七层模型:

这里写图片描述

在OSI七层模型中,每一层的作用对应的协议如下:

这里写图片描述

TCP是一个协议,那这个协议是如何定义的,它的数据格式是什么样子的?那就要进行更深层次的剖析,就需要了解,甚至是熟记TCP协议中的每个字段的含义,如下图:

这里写图片描述

上面就是TCP协议头部的格式,由于它太重要了,所以下面就将每个字段的信息都详细说明下

  • Source Port和Destination Port:分别占用16位,表示源端口号和目的端口号;用于区别主机中的不同进程,IP地址用来区分不同主机的,源端口号和目的端口号配合上IP首部中的源IP地址就能确定为一个TCP连接

  • Sequenece Number:用来标识从TCP发送端向TCP接收端的数据字节流,他表示在这个报文中的第一个数据字节流在数据流中的序号;主要用来解决网络乱序的问题。

  • Acknowledgment Number:32位确认序号包发送确认的一端所期望收到的下一个序号,因此,确认需要应该是上次已成功收到数据字节序号+1,不过只有当标志位中的ACK标志(下面介绍)为1时该确认序列号的字段才有效。主要用来解决不丢包的问题。

  • Offset:给出首部中32bit字的数目,需要这个值是因为任选字段的长度是可变的。这个字段占4bit(最多能表示15个32bit的字,即4*15=60个字节的首部长度),因此TCP最多有60个字节的首部。然而,没有任选字段,正常的长度是20字节。

  • TCP Flags:TCP首部中有6个比特,它们总的多个可同时被设置为1,主要是用于操控TCP的状态机,依次为URG,ACK,PSH,RST,SYN,FIN。

  • Window:窗口大小,也就是有名的滑动窗口,用来进行流量控制;这是一个复杂的问题

TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接:位码即tcp标志位,有6种标示:SYN(synchronous建立联机) ACK(acknowledgement 确认) PSH(push传送) FIN(finish结束) RST(reset重置) URG(urgent紧急)Sequence number(顺序号码) Acknowledge number(确认号码)
现在来介绍一下这些的标志位:

  • URG:次标志表示TCP包的紧急指针域(后面马上就要说到)有效,用来保证TCP连接不被中断,并督促中间层设备要尽快处理这些数据。

  • ACK:此标志表示应答域有效,就是说前面所说的TCP的应答将会包含在TCP数据包中;有两个取值:0和1,为1的时候表示应答域有效,反之为0。

  • PSH:这个标志位表示Push操作。所谓Push操作就是是在数据包到达接受端以后,立即传送给应用程序,而不是在缓冲区排队。

  • RST:这个标志位表示连接复位请求。用来复位哪些产生错误的链接,也被用来拒绝错误和非法的数据包。

  • SYN:表示同步序号,用来建立连接。SYN标志位和ACK标志位搭配使用,当连接请求的时候,SYN=1,ACK=0;连接被响应的时候,SYN=1,ACK=1。这个标志的数据包常常被用来进行端口扫描。扫描者发送一个只有SYN的数据包,如果对方主机响应了一个数据包回来,就表明这台主机存在这个端口,但是由于这种扫描只是进行TCP三次握手的第一次握手,因此这种扫描的成功表明被扫描的机器很不安全,一台安全的主机将会强制要求一个连接严格的进行TCP的三次握手。

  • FIN:表示发送端已经达到数据末尾,也就是说双方数据传送完成,没有数据可以传送了,发送FIN标志位的TCP数据包后,连接将断开。这个表示的数据包也经常被用于进行端口扫描。

讲完标志位后就要开始正式的连接。

二、TCP3次握手和4次挥手

(一)、3次握手

TCP是面向连接的,无论哪一方向另一方发送数据之前,都必须现在双方之间建立一条连接。在TCP/IP协议中,TCP协议提供可靠的连接服务,连接是通过三次握手进行初始化的。三次握手的目的是同步连接双方的序列号和确认号并交换TCP窗口大小的信息。这就是面试中经常被问到的TCP三次握手。那咱们就详细的了解下,看图述说:

这里写图片描述

  • 1、第一次握手:建立连接,客户端先发送连接请求报文,将SYN位置为1,Sequence Number为X;然后,客户端进入SYN+SEND状态,等待服务器的确认;

  • 2、第二次握手:服务器收到SYN报文。服务器收到客户端的SYN报文,需要对这个SYN报文进行确认,设置Acknowledgment Number为x+1(Sequence+1);同时,自己还要送法SYN消息,将SYN位置为1,Sequence Number为y;服务器将上述所有信息放到一个报文段(即SYN+ACK报文段)中,一并发送给客户端,此时服务器进入SYN+RECV状态。

  • 3、第三次握手;客户端收到服务器的 SYN+ACK报文段。然后将Acknowlegment Number设为y+1,向服务器发送ACK报文段,这个报文段发送完毕后,客户端端服务器都进入ESTABLISHED状态,完成TCP三次握手。

实例:

IP 192.168.1.116.3337 > 192.168.1.123.7788: S 3626544836
第一次握手:192.168.1.116发送位码syn=1,随机产生seq
number=3626544836的数据包到192.168.1.123,由SYN=1知道192.168.1.116要求建立联机;

IP 192.168.1.123.7788 > 192.168.1.116.3337: S 1739326486: ack
3626544837 第二次握手:192.168.1.123收到请求后要确认联机信息,向192.168.1.116发送ack
number=3626544837,syn=1,ack=1,随机产生seq=1739326486的包;

IP 192.168.1.116.3337 > 192.168.1.123.7788: ack 1739326487,ack 1
第三次握手:192.168.1.116收到后检查ack number是否正确,即第一次发送的seq
number+1,以及位码ack是否为1,若正确,192.168.1.116会再发送ack
number=1739326487,ack=1,192.168.1.123收到后确认seq=seq+1,ack=1则连接建立成功。

完成了三次握手,客户端和服务器就可以开始传送数据了,以上就是TCP三次握手的总体介绍。

(二)、4次回挥手

当客户端和服务器进行三次握手简历TCP连接以后,当数据传送完毕,肯定要断开TCP连接。那对于TCP的断开,就是”4次挥手”。

  • 1、客户端(也可以是服务器),设置Sequence Number和Acknowledgment Number,向服务器发送一个FIN报文段。此时客户端进入FIN_WAIT_1状态;这表示客户端没有数据发送给主机了。

  • 2、服务器收到客户端发来的FIN报文段,向客户端回一个ACK报文段,Acknowledgement Number为Sequence Number加1;客户端进入FIN_WAIT_2状态,服务器进入CLOSE_WAIT状态;服务器告诉客户端,我同意你的”关闭”请求。

  • 3、服务器向客户端发送FIN报文段,请求关闭连接,同时服务器进入LAST_ACK状态。

  • 4、客户端收到服务器发送的FIN报文段,向主机发送ACK报文段,然后客户端进入TIME_WAIT状态,服务器收到客户端的ACK报文段以后,就关闭连接,此时,客户端等待2MSL后一次没有到收到回复,则证明Server端已正常关闭,那好,客户端也可以关闭连接了。

至此,TCP的四次分手就完成了。

为了让大家更好的理解3次握手和4次挥手,我准备了几道问题,让大家更好的理解3次握手和4次挥手。

1、为什么握手要“3”次?

一般同学会认为,握手为什么要3次,感觉2次就可以了。在谢希仁的<计算机网络>中是这样说的

为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。

在书中同时举了一个例子,如下:

“已失效的连接请求报文段”的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。”
这就很明白了,防止了服务器端的一直等待而浪费资源

2、为什么握手要“3”次,而挥手要”4”次?

TCP协议是一种面向连接的、可靠的、基于字节流的运输层通信协议。TCP是全双工模式,这就意味着,当客户端发起FIN报文段时,只表示客户端已经已经没有数据要发送了,客户端告诉服务器,它的数据已经全部发送完毕了,但是此时客户端还是可以接受服务器的数据;当服务器返回ACK报文段是时,表示它已经知道客户端没有数据发送了,但是服务器还是可以发送数据到客户端;当服务器也发送了FIN报文时,这时候就是表示服务器也没有数据要发送给客户端了,之后就可以愉快地中断这次TCP连接。

为了让大家更好的地理解四次挥手的原理,我们再讲解下四次挥手的状态:

  • 1、FIN_WAIT_1:这个状态要好好解释一下,其实FIN_WAIT_1和FIN_WAIT_2状态的真正含义都是表示等待对方的FIN报文。而这两种状态的区别:FIN_WAIT_1状态实际上是当SOCKET在ESTABLISHED状态时,它想主动关闭连接,向对方发送了FIN报文,此时该SOCKET即进入FIN_WAIT_1状态。而当对方回应ACK报文后,则进入FIN_WAIT_2状态,当然在实际的正常情况下,无论对方何种情况下,都应该马上回应ACK报文,所以FIN_WAIT_1状态一般是比较难见到的,而FIN_WAIT_2状态还有时常常可看到。

  • 2、FIN_WAIT_2:上面已经详细解释了这种状态,实际上 FIN_WAIT_2状态下的SOCKET,表示半连接,既有一方要求close连接,但另外还告诉对方,我暂时还有点数据需要传送给你(ACK信息),稍后再关闭连接

  • 3、CLOSE_WAIT_2:这种状态的含义其实表示在等待关闭。怎么理解?当对方close一个SOCKET后发送一个FIN报文给自己,服务器系统毫无疑问会回应一个ACK报文给对方,此时则进入到CLOSE_WAIT状态。接下来呢,实际上你真正需要考虑的事情是查看你是否还有数据发送给对方,如果没有的话,那么你也就可以close这个这个SOCKET,发送FIN报文给对方,也即关闭连接。所以你在CLOSE_WAIT状态下,需要完成的事情是等待你去关闭连接。

  • 4、LAST_ACK:这个状态还是比较容易好理解的,它是被动关闭一方在发送FIN报文后,最后等待对方的ACK报文。当收到ACK报文后,也可以进入CLOSED状态了。

  • 5、CLOSED:表示连接中断

  • 6、TIME_WAIT:表示收到对方的FIN报文,并发出了ACK报文就等2MSL后即可会到CLOSED可用状态了。如果FIN_WAIT_1下,收到了对方同时带FIN标志和ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态。

3、为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?

虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假设网络是不可靠的,一切都可能发生,比如有可能最后一个ACK丢失。所以TIME_WAIT状态是用来重发可能丢失的ACK报文。

原创粉丝点击