iOS接下来要研究的知识点计网程序猿阵线联盟-汇总各类技术干货

TCP与UDP(七)

2017-10-29  本文已影响181人  ZhengYaWei

TCP/IP 系列文章

网络基础知识(一)
TCP/IP基础知识(二)
物理层(三)
数据链路层(四)
IP 协议(五)
IP 协议相关技术(六)
TCP与UDP(七)

一、传输协议层

1.1 两种传输层协议 UDP 和 TCP

在 TCP/IP 中能够实现传输功能的,并具有代表性的协议是 TCP 和 UDP 这两个协议。两者都是流协议,你可以把它想象成排水管中的水流。

TCP 协议能够正确处理丢包问题,保证接收方能够收到数据,与此同时还能够有效利用网络带宽。然而 TCP 协议中定义了很多复杂的规范,因此效率不如 UDP 协议,不适合实时的视频和音频传输。

UDP 协议是面向无连接的协议,它只会把数据传递给接收端,但是不会关注接收端是否真的收到了数据。但是这种特性反而适合多播,实时的视频和音频传输。因为个别数据包的丢失并不会影响视频和音频的整体效果。

1.2.1 UDP 首部

UDP 的首部结构比较简单,如下图所示。



UDP 首部包含源端口号、目标端口号、包长度和校验和。其中包长度表示 UDP 首部的长度和 UDP 数据长度之和。另外,校验和用来判断数据在传输过程中是否损坏。计算这个校验和的时候,不仅考虑源端口号和目标端口号,还要考虑 IP 首部中的源 IP 地址,目标 IP 地址和协议号(这些又称为 UDP 伪首部)。这是因为以上五个要素用于识别通信时缺一不可,如果校验和只考虑端口号,那么另外三个要素收到破坏时,应用就无法得知。这有可能导致不该收到包的应用收到了包,该收到包的应用反而没有收到。这个概念同样适用于即将介绍的 TCP 首部。

1.2.2 TCP 首部
TCP 首部

毫无疑问,TCP 首部的结构要比 UDP 复杂的多。这也是 TCP 传输速度低于 UDP 的重要原因之一。

1.2 关于端口号(扩充)

首先要知道,只有在目标地址、原地址、目标端口号、源端口号以及协议类型(TCP 还是 UDP)这五项内容都一致的时候才被认为是同一个通信连接。


服务端程序在 UNIX 系统中叫做守护进程。如 HTTP 的服务端程序是 httpd(HTTP 守护进程),而 sshd (SSH 守护进程)。在 UNIX 中并不需要将这些守护进程逐个启动,而是启动一个可以代表他们接收到客服端请求的 inetd(互联网进程)服务程序即可。传输协议 TCP 、UDP 通过接受数据中的目标端口号识别处理程序。

二、TCP 连接和断开(三次连接,四次挥手断开连接)

关于 TCP 连接和断开连接的过程,可以参考下图。


连接和断开连接

2.1 关于三次握手连接

三次握手建立连接流程:
为什么要三次握手,尤其是为何执行第三步?

一般的思路可能会觉得只要两次握手就可以了,第三步确认似乎是多余的。其实不然,网络是不可靠的,数据包是可能丢失的。假设没有第三次确认,客户端向服务端发送了 SYN 请求建立连接。由于延迟,服务端没有及时收到这个包。于是客户端重新发送一个 SYN 包。假设服务端接收到了第二个 SYN 包,建立了通信,一段时间后通信结束,连接被关闭。这时候最初被发送的 SYN 包刚刚抵达服务端,服务端又会发送一次 ACK 确认。由于两次握手就建立了连接,此时的服务端就会建立一个新的连接,然而客户端觉得自己并没有请求建立连接,所以就不会向服务端发送数据。从而导致服务端建立了一个空的连接,白白浪费资源。但是在有了第三步确认时情况就不一样了,服务端直到收到客户端的应答后才会建立连接。如果客户端接受到一个相同的 ACK 包,这时候它会抛弃这个数据包,不会和服务端再次进行,因此避免了服务端建立空的连接。

建立连接过程中, ACK 确认丢失后,TCP 协议是如何处理?

按照 TCP 协议处理丢包的一般方法,服务端会重新向客户端发送数据包,直至收到 ACK 确认为止。但实际上这种做法有可能遭到 SYN 泛洪攻击。所谓的泛洪攻击,是指发送方伪造多个 IP 地址,模拟三次握手的过程。当服务器返回 ACK 后,攻击方故意不确认,从而使得服务器不断重发 ACK。由于服务器长时间处于半连接状态,最后消耗过多的 CPU 和内存资源导致死机。

正确处理方法是服务端发送 RST 报文,进入 CLOSE 状态。这个 RST 数据包的 TCP 首部中,控制位中的 RST 位被设置为 1。这表示连接信息全部被初始化,原有的 TCP 通信不能继续进行。客户端如果还想重新建立 TCP 连接,就必须重新开始一次握手。

2.2 关于四次挥手断开连接

四次挥手断开连接过程:
为什么都要执行关闭操作?

因为连接是双向的,所以双方都要主动关闭自己这一侧的连接。

ACK 丢失怎么办?

在第三步中,客户端收到 FIN 包时,会设置一个计时器,等待相当长的一段时间。如果客户端返回的 ACK 丢失,那么服务端还会重发 FIN 并重置计时器。假设在计时器失效前服务器重发的 FIN 包没有到达客户端,客户端就会进入 CLOSE 状态,从而导致服务端永远无法收到 ACK 确认,也就无法关闭连接。

三、TCP 数据包重发

丢失数据包再次重发的前提是发送方能够知道接收方是否成功的接收了消息。

通过序列号和确认应答提高可靠性

TCP 中,当发送端的数据到达接收端时,接收端会返回一个已收到消息的回执通知,该回执通知叫做确认应答 ACK 。根据 上面对 TCP 首都的分析可知,该 ACK 的值和发送端下次发送数据包在整个发送数据中的序列号相等。更明确的说,ACK 除了告诉发送端已经接收到了当前数据包,还告诉发送端下次发送数据要从那个位置开始发。如下示意图。

然而,实际情况并不总是那么尽如人意。比如下面这两个问题:
1、因为网络问题,如果数据包和 ACK 应答都丢失,怎么办?
此时,发送方如果在一段时间内没有收到 ACK,就会重发数据。
2、由于网络延迟的存在,接收方收到重复的数据包怎么办?
通过 TCP 首部中的 SYN 判断这个数据包是否曾经接收过。如果已经接收过,就会丢弃这个包。

未收到ACK重发过程

TCP 窗口

发送端在数据包发出后,直至 ACK 确认返回以前,发送端都无法发送数据,显然是一种浪费,网络利用效率和通信性能就越低。这一问题在 TCP 中通过引入”窗口“的概念得以被解决。

利用窗口控制提高速度

”窗口大小“表示无需等待确认应答ACK返回之前,可以继续发送数据包的最大数量。

窗口的控制和重发控制

以下示意图是窗口控制的概念。


高速重发机制
上一篇下一篇

猜你喜欢

热点阅读