多语言展示
当前在线:785今日阅读:75今日分享:44

TCP 协议中的三次握手与四次挥手

1、TCP、UDP 协议的区别 2、TCP 头部结构 3、三次握手与四次挥手过程详解 4、什么是 TIME_WATI 状态
方法/步骤
1

TCP、UDP 协议的区别:1、首页它们俩都是传输层的协议,而所谓“传输层”,它是为两台主机提供端到端的通信,即从 A <-> B 。2、TCP 协议可靠,UDP 协议不可靠。可靠即指数据由 A 发送到 B,是否能确保数据真的有送达到 B。TCP 协议使用 超时重传、数据确认等方式来确保数据包被正确地发送至目的端,而 UDP 协议无法保证数据从发送端正确传送到目的端,如果数据在传输过程中丢失、或者目的端通过数据检验发现数据错误,则 UDP 协议只是简单地通知应用程序发送失败,对于 TCP 协议拥有的超时重传、数据确认等需要应用程序自己来处理这些逻辑。3、TCP 是面向连接的,UDP 是无连接的。这也比较好理解,因为 TCP 连接才需要“三次握手,四次挥手”。4、TCP 服务是基于流的,而 UDP 是基于数据报的,基于流的数据没有边界(长度)限制,而基于数据报的服务,每个 UDP 数据报都有一个长度,接收端必须以该长度为最小单位将其所有内容一次性读出。5、当发送方多次执行写操作时,TCP 模块会先将这些数据放入 TCP 发送缓冲区中,当 TCP 模块真正开始发送数据时,发送缓冲区中这些等待发送的数据可能被封装成一个或多个 TCP 报文段发出,因此,TCP 模块发出的 TCP 报文段的个数与应用程序执行的写操作次数是没有固定数量关系的。同样,当接收端收到一个或多个 TCP 报文段后,TCP 模块将这些数据按照序号(序号说明见下面 的 TCP 头部结构)依次放入 TCP 接收缓冲区中,并通知应用程序读取数据。接收端可选择一次或者分多次将数据从缓冲区中读出(这取决于用户指定的应用程序读缓冲区的大小)。因此,接收端读取数据的次数与发送端发出多少个报文段个数也没有固定的数量关系。总结来说,即对于 TCP 连接,发送端执行的写操作次数与接收端执行的读操作次数之间没有任何数据关系,这也是基于流服务的特点。而对于 UDP 服务,发送端每执行一次写操作,就会将其封装成一个 UDP 数据报并发送之,同时接收端必须根据发送的进行读,否则就会丢包。因此,对于 UDP 连接,发送端写的次数据与读的次数是一致的,这也是基于数据报的服务的特点。6、TCP 的连接是一对一的,所以如果是基于广播或者多播的的应用程序不能使用 TCP,而 UDP 则非常适合广播和多播。

2

TCP 头部结构16位源端口号与目的端口号,这个比较好理解,就不过多解释。32位序号:该序号为生成的随机值 ISN 加上该段报文段所携带的数据的第一个字节在整个字节流中的偏移量。比如,某个 TCP 报文段发送的数据是字节流中的第 100 ~ 200 字节,那该序号为 ISN + 1004位头部长度:标识 TCP 头部有多少个 32 bit 字,因为是 4位,即 TCP 头部最大能表示 15,即最长是 60 字节。即它是用来记录头部的最大长度。6位标志位,包括: URG 标志:表示紧急指针是否有效。 ACK 标志:确认标志。通常称携带 ACK 标志的 TCP 报文段为确认报文段。 PSH 标志:提示接收端应该程序应该立即从 TCP 接收缓冲区中读走数据,为接收后续数据腾出空间(如果不读走,数据就会一直在缓冲区内)。 RST 标志:表示要求对方重新建立连接。通常称携带 RST 标志的 TCP 报文段为复位报文段。 SYN 标志:表示请求建立一个连接。通常称携带 SYN 标志的 TCP 报文段称为同步报文段。 FIN 标志:关闭标志,通常称携带 FIN 标志的 TCP 报文段为结束报文段。 这些标志位说明了当前请求的目的,即要干什么。16 位窗口大小:表示当前 TCP 接收缓冲区还能容纳多少字节的数据,这样发送方就可以控制发送数据的速度,它是 TCP 流量控制的一个手段。16 位校验和:验证数据是否损坏,通过 CRC 算法检验。这个校验不仅包括 TCP 头部,也包括数据部分。16 位紧急指针:正的偏移量,它和序号字段的值相加表示最后一个紧急数据的下一字节的序号。TCP 的紧急指针是发送端向接收端发送紧急数据的方法。TCP 头部选项:可变长的可选信息,这部分最多包含 40 字节,因为 TCP 头部最长是 60 字节,所以固定部分占 20 字节。这里不做详细介绍,可以参考《Linux高性能编程》3.2.2

3

先来解释三次握手过程:1、发送端发送连接请求,6位标志为 SYN,同时带上自己的序号(此时由于不传输数据,所以不表示字节的偏移量),比如是 223。2、接收端接到请求,表示同意连接,发送同意响应,带上 SYN + ACK 标志位,同时将确认序号为 224(发送端序号加1),并带上自己的序号(此时同样由于不传输数据,所以不表示字节的偏移量),比如是 521。3、发送端接收到确认信息,再发回给接收端,表示我已接受到你的确认信息,此时标志仍为 ACK,确认序号为 522。

4

接着我们来看看四次挥手过程:1、发送方发送关闭请求,标志位为:FIN,同时也会带上自己的序号(此时同样由于不传输数据,所以不表示字节的偏移量)。2、接收方接到请求后,回复确认:ACK,同时确认序号为请求序号加1。3、接收方也决定关闭连接,发送关闭通知,标志位为 FIN,同时还会带上第2步中的确认信息,即 ACK,以及确认序号和自己的序号。4、发送方回复确认信息:ACK,接收方序号加1。

5

涉及到的问题:为什么是三次握手,而不是四次或者两次?首先解释为什么不是四次。四次的过程是这样的:发送方:我要连你了。 接收方:好的。 接收方:我准备好了,你连吧。 发送方:好的。显然接收方准备好连接并同意连接是可以合并的,这样可以提高连接的效率。再来,我们解释为什么不是两次。其实也比较好理解,我们知道 TCP 是全双工通信的,同时也是可靠的,连接和关闭都是两边都要执行才算真正的完成,同时还需要确保两端都已经执行了连接或者关闭。如果只有两次,过程是这样的:发送方:我要连你了。 接收方:好的。很明显,接收方并不知道也不能保证发送方一定接收到 “好的” 这条信息,一旦接收方真的没有收到这条信息,就会出现接收收“单方面连接”的情况,这个时候发送方就会一直重试发送连接请求,直到真正收到 “好的” 这条信息之后才算连接完成。而对于三次,如果发送方没有等待到你回复确认,它是不会真正处于连接状态的,它会重试确认请求。

6

涉及到的问题:为什么需要四次握手,不是三次?三次的过程是这样的:发送方:我不再给你发送数据了。 接收方:好的,我也不给你发了。 发送方:好的,拜拜。这是因为当接收方收到关闭请求后,它能立马响应的就是确认关闭,它这里确认的是接收方的关闭,即发送方不再发数据给接收方了,但他还是可以接收接收方发给他的数据。而接收方是否需要关闭“发送数据给发送方”这条通道,取决于操作系统。操作系统也有可能 sleep 个几秒再关闭,如果合并成三次,就可能造成接收方不能及时收到确认请求,可能造成超时重试等情况。因此需要四次。

推荐信息