- 文章涵盖内容较多,相关内容以链接形式给出,读者自行阅读
一、格式
TCP
- TCP报文段的封装如下:
- TCP头部如下:
UDP
- UDP报文段的封装如下:
- UDP头部如下:
二、TCP的特点
可靠性
- TCP还提供了可靠性(reliability)。当TCP向另一端发送数据时,它要求对端返回一 个确认。如果没有收到确认,TCP就自动重传数据并等待更长时间。在数次重传失败后,TCP才放弃,如此在尝试发送数据上所花的总时间一般为4~10分钟(依赖于具体实现)
- 注意,TCP并不保证数据一定会被对方端点接收,因为这是不可能做到的。如果有可能, TCP就把数据递送到对方端点,否则就(通过放弃重传并中断连接这一手段)通知用户。这 么说来,TCP也不能被描述成是100%可靠的协议,它提供的是数据的可靠递送或故障的可靠通知
RTT算法
- TCP含有用于动态估算客户和服务器之间的往返时间(round-trip time,RTT)的算法,以便它知道等待一个确认需要多少时间。举例来说,RTT在一个局域网上大约是几毫秒,跨越一 个广域网则可能是数秒钟。另外,因为RTT受网络流通各种变化因素影响,TCP还持续估算一 个给定连接的RTT
数据的排序与重复丢弃
- TCP通过给其中每个字节关联一个***对所发送的数据进行排序(sequencing)。举例来 说,假设一个应用写2048字节到一个TCP套接字,导致TCP发送2个分节:第一个分节所含数据 的***为1~1024,第二个分节所含数据的***为1025~2048。(分节是TCP传递给IP的数 据单元。)如果这些分节非顺序到达,接收端TCP将先根据它们的***重新排序,再把结果数据传递给接收应用
- 如果接收端TCP接收到来自对端的重复数据(譬如说对端认为一个分节已丢失并因此重传,而这个分节并没有真正丢失,只是网络通信过于拥挤),它可以(根据***) 判定数据是重复的,从而丢弃重复数据
流量控制
- TCP提供流量控制(flow control)。TCP总是告知对端在任何时刻它一次能够从接收多少字节的数据,这称为通告窗口(advertised window)。在任何时刻,该窗口指出接收缓 冲区中当前可用的空间量,从而确保发送端发送的数据不会使接收缓冲区溢出。该窗口时刻动 态变化:当接收到来自发送端的数据时,窗口大小就减小,但是当接收端应用从缓冲区中读取 数据时,窗口大小就增大。通告窗口大小减小到0是有可能的:当TCP对应某个套接字的接收缓 冲区已满,导致它必须等待应用从该缓冲区读取数据时,方能从对端再接收数据
全双工与单工
- TCP连接是全双工的(full-duplex)。这意味着在一个给定的连接上应用可以在任何时刻在进出两个方向上既发送数据又接收数据。因此,TCP必须为每个数据流方向跟踪诸如***和通告窗口大小等状态信息
- 建立一个全双工连接后,需要的话可以把它转换成一个单工连接
三、UDP的特性
-
它不提供差错纠正、队列管理、重复消除、流量控制和拥塞控制
- 不提供差错纠正:它把应用程序传给IP层的数据发送出去,但是并不保证它们能够到达目的地
- 不提供流量控制:没有协议机制防止高速UDP流量对其他网络用户的消极影响
- 它提供差错检测,包含我们在传输层中碰到的第 一个真实的端到端( end-to-end)校验和
- 这种协议自身提供最小功能,因此使用它的应用程序要做许多关于数据包如何发送和处理的控制工作。想要保证数据被可靠投递或正确排序,应用程序必须自已实现这些保护功能
- 一般来说,每个被应用程序请求的UDP输出操作只产生一个UDP数据报,从而发送一个IP数据报。这不同于面向数据流的协议,例如TCP,应用程序写人的全部数据与真正在单个IP数据报里传送的或接收方接收的内容可能没有联系
-
优点:
- 因为它的无连接特征,它要比其他的传输协议使用更少的开销
- 另外,广播和组播操作更多直接使用像UDP这样的无连接传输
- 最后,应用程序可选择自已的重传单元的能力是一项重要的考虑
- 我们可以使用UDP来检查互联网校验以及观察IP分片如何进行(在后面介绍)
四、三次握手、四次挥手
TCP连接的建立分为3步:
- 1.主动开启者(通常称为客户端)发送一个SYN报文段(即一个在TCP头部的SYN位字段置位的TCP/IP数据包),并指明自己想要连接的端口号和它的客户端初始***(记为ISN(c),本文下面介绍)。通常,客户端还会借此发送一个或多个选项。客户端发送的这个SYN报文段称作段1
- 2.服务器也发送自已的SYN报文段作为响应,并包含了它的初始***(记作ISN(s))。该段称作段2。此外,为了确认客户端的SYN,服务器将其包含的ISN(c)数值加1后作为返回的ACK数值。因此,每发送一个SYN,***就会自动加1。这样如果出现丢失的情况,该SYN段将会重传
- 3.为了确认服务器的SYN,客户端将ISN(s)的数值加1后作为返回的ACK数值。这称为段3
- 简化之后如下图所示:(在显示相关状态的同时省略了选项与初始***等细节)
- 通过发送上述3个报文段就能够完成一个TCP连接的建立。它们也常称作三次握手。 三次握手的目的不仅在于让通信双方了解一个连接正在建立,还在于利用数据包的选项来承载特殊的信息,交换初始***(Initial Sequence Number。ISN)
- 发送首个SYN的一方被认为是主动地打开一个连接。如上文所述,它通常是一个客户端。连接的另一方会接收这个SYN,并发送下一个SYN,因此它是被动地打开一个连接。 通常,这一方称为服务器 (后面将会介绍一种客户端与服务器同时打开一个连接的情况,但非常少见)
TCP连接的关闭分为4步:
- 1.连接的主动关闭者发送一个FIN段指明接收者希望看到的自已当前的***(K)。FIN段还包含了一个ACK段用于确认对方最近一次发来的数据(标记为L)
- 2.连接的被动关闭者将K的数值加1作为响应的ACK值,以表明它已经成功接收到主动关闭者发送的FIN。此时,上层的应用程序会被告知连接的另一端已经提出了关闭的请求。通常,这将导致应用程序发起自已的关闭操作
- 3.接着,被动关闭者将身份转变为主动关闭者,并发送自已的FIN。该报文段的***为L
- 4.为了完成连接的关闭,最后发送的报文段还包含一个ACK用于确认上一个FIN。值得注意的是,如果出现FIN丢失的情况,那么发送方将重新传输直到接收到一个ACK确认为止
- 简化之后如下图所示:(在显示相关状态的同时省略了选项与初始***等细节)
- 连接的任何一方都能够发起一个关闭操作。此外,该过程还支持双方同时关闭连接的操作,但这种情况非常少见
- 在传统的情况下,负责发起关闭连接的通常是客户端。然而,一些服务器(例如web服务器)在对请求做出响应之后也会发起一个关闭操作。通常一个关闭操作是由应用程序提出关闭连接的请求而引发的(例如使用系统调用close)
- TCP协议规定通过发送一个FIN段(即FIN位字段置位的TCP报文段)来发起关闭操作。只有当连接双方都完成关闭操作后,才构成一个完整关闭
五、TCP半关闭
- 如前所述,TCP支持半关闭操作。虽然一些应用需要此项功能,但它并不常见
- 为了实现这一特性,API必须为应用程序提供一种基本的表达方式。例如,应用程序表明“我已经完成了数据的发送工作,并发送一个FIN给对方,但是我仍然希望接收来自对方的数据直到它发送一个FIN给我” 。伯克利套接字的API提供了半关闭操作。应用程序只需要调用shutdown()函数来代替基本的cIose()函数,就能实现上述操作。然而,绝大部分应用程序仍然会调用close()函数来同时关闭一条连接的两个传输方向
- shutdown系统调用参阅:https://blog.csdn.net/qq_41453285/article/details/89647130
- close系统调用参阅:https://blog.csdn.net/qq_41453285/article/details/89179532
图示
- 下图展示了一个正在使用的半关闭示例。图中左侧的客户端负责发起半关闭操作,然而在实际应用中,通信的任何一方都能完成这项工作
- 首先发送的两个报文段与TCP正常关闭完全相同:初始者发送的FIN,接着是接收者回应该FIN的ACK
- 由于接收到半关闭的一方仍能够发送数据,因此下图中的后续操作与四次挥手关闭连接的情况不同不同。虽然下图在ACK之后只描述了一个数据段的传输过程,但实际应用时可以传输任意数量的数据段(后面“TCP数据流与窗口管理”将会详细地讨论数据段的交换与确认细节)。当接收半关闭的一方完成数据发送后,它将会发送一个FIN来关闭本方的连接,同时向发起半关闭的应用程序发出一个文件尾指示。当第2个FIN被确认之后,整个连接完全关闭
六、TCP的同时打开
- 虽然两个应用程序同时主动打开连接看似不大可能,但是在特定安排的情况下是有可能实现的。通信双方在接收到来自对方的SYN之前必须先发送一个SYN;两个SYN必须经过网络送达对方。该场景还要求通信双方都拥有一个IP地址与端口号,并且将其告知对方。 上述情况十分少见(前面文章介绍的防火墙“打孔”技术除外),一旦发生,可称其为同时打开
-
例如:
- 主机A的一个应用程序通过本地的7777端口向主机B的8888端口发送一个主动打开请求,与此同时主机B的一个应用程序也通过本地的8888端口向主机A的7777端口提出一个主动打开请求,此时就会发生一个同时打开的情况
- 这种情况不同于主机A的一个客户端连接主机B的一个服务器,而同时又有主机B的一个客户端连接主机A的一个服务器的情况。在这种情况下,服务器始终是连接的被动打开者而非主动打开者,而备自的客户端也会选择不同的端口号。因此,它们可以被区分为两个不同的TCP连接
图例
- 下图显示了在一个同时打开过程中报文段的交换情况
- 一个同时打开过程需要交换4个报文段,比普通的三次握手增加了一个
- 由于通信双方都扮演了客户端与服务器的角色,因此不能够将任何一方称作客户端或服务器
七、TCP的同时关闭
- 同时关闭与同时连接并没有太大区别
- 前面的正常关闭过程,通信一方(通常是客户端,但不一定总是)提出主动关闭请求,并发送首个FIN。在同时关闭中,通信双方都会完成上述工作
图例
- 下图显示了在一个同时关闭中需要交换的报文段
- 同时关闭需要交换与正常关闭相同数量的报文段。两者真正的区别在于:报文段序列是交叉的还是顺序的。下文将会介绍TCP实现中同时打开与同时关闭操作使用特殊状态这一不常见的方法
- 同时打开与同时关闭还可以参阅:https://blog.csdn.net/qq_41453285/article/details/104041073
八、TCP与UDP的区别
TCP优点
- 可靠,稳定 TCP的可靠体现在TCP在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制,在数据传完后,还会断开连接用来节约系统资源。 TCP的缺点: 慢,效率低,占用系统资源高,易被攻击 TCP在传递数据之前,要先建连接,这会消耗时间,而且在数据传递时,确认机制、重传机制、拥塞控制机制等都会消耗大量的时间,而且要在每台设备上维护所有的传输连接,事实上,每个连接都会占用系统的CPU、内存等硬件资源。 而且,因为TCP有确认机制、三次握手机制,这些也导致TCP容易被人利用,实现DOS、DDOS、CC等攻击
UDP优点
- 快,比TCP稍安全 UDP没有TCP的握手、确认、窗口、重传、拥塞控制等机制,UDP是一个无状态的传输协议,所以它在传递数据时非常快。没有TCP的这些机制,UDP较TCP被攻击者利用的漏洞就要少一些。但UDP也是无法避免攻击的,比如:UDP Flood攻击…… UDP的缺点: 不可靠,不稳定 因为UDP没有TCP那些可靠的机制,在数据传递时,如果网络质量不好,就会很容易丢包。 基于上面的优缺点,那么: 什么时候应该使用TCP: 当对网络通讯质量有要求的时候,比如:整个数据要准确无误的传递给对方,这往往用于一些要求可靠的应用,比如HTTP、HTTPS、FTP等传输文件的协议,POP、SMTP等邮件传输的协议。 在日常生活中,常见使用TCP协议的应用如下: 浏览器,用的HTTP FlashFXP,用的FTP Outlook,用的POP、SMTP Putty,用的Telnet、SSH QQ文件传输 ………… 什么时候应该使用UDP: 当对网络通讯质量要求不高的时候,要求网络通讯速度能尽量的快,这时就可以使用UDP。 比如,日常生活中,常见使用UDP协议的应用如下: QQ语音 QQ视频 TFTP ……
-
小结:
-
基于连接与无连接
-
对系统资源的要求(TCP较多,UDP少)
-
UDP程序结构较简单
-
流模式与数据报模式
-
TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证
- UDP不提供可靠性。UDP本身不提供确认、***、RTT估算、超时和重传等机制。如果一个UDP数据报在网络中被复制,两份副本就可能都递送到接收端的主机。同样地,如果 一个UDP客户发送两个数据报到同一个目的地,它们可能被网络重新排序,颠倒顺序后到达 目的地。UDP应用必须处理所有这些情况
- UDP不提供流量控制,让较快的UDP发送端以一个UDP接收端 难以跟上的速率发送数据报是非常容易的
- UDP可以是全双工的
-