一文弄懂TCP与UDP
TCP协议和UDP协议与TCP/IP协议的联系
TCP/IP协议是一个协议簇。里面包括很多协议的,UDP只是其中的一个, 之所以命名为TCP/IP协议,因为TCP、IP协议是两个很重要的协议,就用他两命名了。
TCP/IP协议集包括应用层,传输层,网络层,数据链路层。
TCP和UDP
TCP,Transmission Control Protocol:传输控制协议,可靠的、面向连接的、基于字节流的传输层通信协议。
UDP,User Data Protocol:用户数据报协议,不可靠,无连接的服务。
当设计一个网络应用程序时,开发人员应指定使用两种运输协议的一种。(生成socket时必须指定TCP还是UDP)
简单介绍网络层
网络层有个地址叫IP,即网际协议。IP为主机间提供逻辑通信。
IP不确保报文段的交付,不能保证报文段按序交付。所以也被称为不可靠服务。
每台主机至少有一个网络层地址,即所谓的IP地址。
UDP和TCP的基本职责是,将两个端系统间IP的交付服务扩展成运行在端系统上的两个进程之间的交付服务。
UDP:无连接传输
UDP只做了传输协议能做的最少工作,即复用/分解以及少量差错检测,几乎没对IP增加其他东西。
为何说UDP是无连接传输?
在使用UDP时,在发送报文前,发送方和接收方的传输层实体之间没有握手。正因如此,UDP被称为无连接。
UDP有什么特点?
(1) UDP是无连接的,即发送数据之前不需要建立连接,因此减少了开销和发送数据之前的时延。
(2) UDP使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的连接状态表。
(3) UDP是面向报文的。发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付IP层。UDP对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。因此,应用程序必须选择合适大小的报文。
(4) UDP没有拥塞控制,因此网络出现的拥塞不会使源主机的发送速率降低。很多的实时应用(如IP电话、实时视频会议等)要去源主机以恒定的速率发送数据,并且允许在网络发生拥塞时丢失一些数据,但却不允许数据有太多的时延。UDP正好符合这种要求。
(5) UDP支持一对一、一对多、多对一和多对多的交互通信。
(6) UDP的首部开销小,只有8个字节,比TCP的20个字节的首部要短。
注意:
(1) 不使用拥塞控制功能的UDP有可能会引起网络产生严重的拥塞问题。
(2) 一些使用UDP的实时应用进程本身可以在不影响应用的实时性的前提下,增加一些提高可靠性的措施,如采用前向纠错或重传已丢失的报文。
UDP首部的格式?
UDP有两个字段:数据字段和首部字段。首部字段很简单,只有8个字节,由4个字段组成,每个字段的长度都是两个字节。各字段意义如下:
- 源端口:源端口号。在需要对方回信时选用。不需要时可用全0。
- 目的端口:目的端口号。这在终点交付报文时必须要使用到。
- 长度: UDP用户数据报的长度,其最小值是8(仅有首部),发送一个带0字节数据的UDP数据报是允许的。值得注意的是,UDP长度字段是冗余的;IPV4头部包含了数据报的总长度,同时IPV6头部包含了负载长度。因此,一个UDP/IPV4数据报的长度等于IPV4数据报的总长度减去IPV4头部的长度。一个UDP/IPV6数据报的长度等于包含在IPV6头部中的负载长度(payload length)字段的值减去所有扩展头部(除非使用了超长数据报)的长度。这两种情况下,UDP长度字段应该与从IP层提供的信息计算得到的长度是一致的。
- 校验和:检测UDP用户数据报在传输中是否有错。有错就丢弃。
伪首部
在UDP伪首部中,包含32位源IP地址,32位目的IP地址,8位填充0,8位协议,16位UDP长度。伪首部并非TCP&UDP数据报中实际的有效成分。伪首部是一个虚拟的数据结构,其中的信息是从数据报所在IP分组头的分组头中提取的,既不向下传送也不向上递交,而仅仅是为计算校验和。
伪头部的目的是让UDP层验证数据是否已经到达正确的目的地(即,该IP没有接受地址错误的数据报,也没有给UDP一个本该其他传输协议的数据报),计算UDP校验和时覆盖的字段,包含了伪头部以及UDP头部和负载。
TCP:面向连接的传输
TCP连接是全双工,点对点。
TCP连接的端点即套接字。
套接字socket = (IP地址+端口号)
TCP连接={socket1,socket2}={(IP1:port1),(IP2,port2)}
tcp标志位,有6种标示:
- SYN(synchronous建立联机)
- ACK(acknowledgement 确认)
- PSH(push传送)
- FIN(finish结束)
- RST(reset重置)
- URG(urgent紧急)
- Sequence number(顺序号码)
- Acknowledge number(确认号码)
TCP首部字段是如何划分的?
MSS:最大报文长度
TCP报文段由20字节首部字段和数据字段组成。MSS限制了报文段数据字段的最大长度。
首部中的重要概念
与UDP一样包括源端口号和目的端口号还有校验和。
序号:Seq序号,占32位。用于说明当前数据第一个字节在所有数据(整个文件)中的位置
确认号:Ack序号,占32位。用于告诉发送者接下来需要发送的数据序号。
序号和确认号用于实现可靠数据传输。
接收窗口:用于流量控制。
数据偏移:用于说明首部长度。(比如1111说明首部长为15*4字节)
标志位:tcp标志位有6种;
不要将确认序号Ack与标志位中的ACK搞混
TCP是如何创建连接的?
建立连接的Python代码:
clientSocket.connect((serverName,serverPort))
serverName:服务器名字,serverPort:标识服务器上的进程
三次握手(报文交换):
第一次握手:主机A发送位码为syn=1,随机产生seq number=1234567的数据包到服务器,主机B由SYN=1知道,A要求建立联机;
第二次握手:主机B收到请求后要确认联机信息,向A发送ack number=(主机A的seq+1),syn=1,ack=1,随机产生seq=7654321的包;
第三次握手:主机A收到后检查ack number是否正确,即第一次发送的seq number+1,以及位码ack是否为1,若正确,主机A会再发送ack number=(主机B的seq+1),ack=1,主机B收到后确认seq值与ack=1则连接建立成功。
三次握手的第三个阶段可以在报文中携带客户到服务器中的数据。
一旦完成这三个步骤,客户端和主机就可以发送报文段了。在以后每一个报文段中,SYN比特都将被置为0。
TCP是如何取消连接的?
TCP连接的两个进程中的任何一个都能终止该连接。
四次挥手:
1)第一次挥手:客户端向服务器发起请求释放连接的TCP报文,置FIN为1。客户端进入终止等待-1阶段。
2)第二次挥手:服务器端接收到从客户端发出的TCP报文之后,确认了客户端想要释放连接,服务器端进入CLOSE-WAIT阶段,并向客户端发送一段TCP报文。客户端收到后进入种植等待-2阶段。
3)第三次挥手:服务器做好了释放服务器端到客户端方向上的连接准备,再次向客户端发出一段TCP报文。。此时服务器进入最后确认阶段。
4)第四次挥手:客户端收到从服务器端发出的TCP报文,确认了服务器端已做好释放连接的准备,于是进入时间等待阶段,并向服务器端发送一段报文。
注意:第四次挥手后客户端不会立即进入closed阶段,而是等待2MSL再关闭。
为何是2MSL的时间?
2MSL是报文一个往返的最长时间,假设小于这个时间会发生,ACK丢了,但是还没接收到对方重传的FIN我方就重新发送了ACK。
若通信双方同时打开/关闭连接,怎么处理?
还有一种比较非常规的操作,这就是两个应用程序同时主动打开连接。虽然这种情况看起来不太可能,但是在特定的安排下却是有可能发生的。我们主要讲述这个过程。
通信双方在接收到来自对方的 SYN 之前会首先发送一个 SYN,这个场景还要求通信双方都知道对方的 IP 地址 + 端口号。
下面是同时打开的例子:
如上图所示,通信双方都在收到对方报文前主动发送了 SYN 报文,都在收到彼此的报文后回复了一个 ACK 报文。
一个同时打开过程需要交换四个报文段,比普通的三次握手增加了一个,由于同时打开没有客户端和服务器一说,所以这里我用了通信双方来称呼。
像同时打开一样,同时关闭也是通信双方同时提出主动关闭请求,发送 FIN 报文,下图显示了一个同时关闭的过程。
同时关闭过程中需要交换和正常关闭相同数量的报文段,只不过同时关闭不像四次挥手那样顺序进行,而是交叉进行的。
TCP如何确保可靠性传输?
停止等待:需要停止等待确认,若设定时间内未收到确认则进行超时重传。这样可以保证对方确认收到后,再发送下一段报文。
确认丢失与确认迟到:
上述的确认和重传机制,可以称为自动重传机制:ARQ(Automatic repeat reQuest)
但是简单的停止等待方式信道利用率较低,为此采用流水线传输方式。
流水线传输:
发送方可连续发送多个分组,不必每发完一个分组就停顿下来等待对方的确认。由于信道上一直有数据不间断的传送,这种传输方式可获得很高的信道利用率。
累计确认:
接收方一般采用累计确认的方式表明自己已经连续接收到哪个地方了。
如果已经建立了连接,但是客户端突然出现故障了怎么办?
这个不难TCP自己做了保证,TCP默认有个定时器,每次收到客户端的请求后会把定时器设置好,通常设置两小时,超过两小时还没收到数据。
服务端会发送一个探测报文,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。
如何理解TCP的流量控制?
流量控制:
如果发送者发送数据过快,接收者来不及接收,那么就会有分组丢失。为了避免分组丢失,控制发送者的发送速度,使得接收者来得及接收,这就是流量控制。流量控制根本目的是防止分组丢失,它是构成TCP可靠性的一方面。
实现流量控制:
由滑动窗口协议(连续ARQ协议)实现。滑动窗口协议既保证了分组无差错、有序接收,也实现了流量控制。主要的方式就是接收方返回的 ACK 中会包含自己的接收窗口的大小,并且利用大小来控制发送方的数据发送。
如何理解TCP的拥塞控制?
拥塞控制是为了解决过多的数据注入到网络,导致网络奔溃,超过负荷,拥塞控制包含四个策略
-
慢开始
慢开始的含义就是讲窗口先设置为1,每个传输轮次大小增长一倍,直到大道慢开始的门限(ssthresh),这时候慢开始阶段结束
-
拥塞避免
慢开始结束后,接下来就是拥塞避免,这个阶段拥塞窗口在每个传输轮次数量加1,直到触发了网络拥塞,窗口大小和门限都变为拥塞时最大的值得一半,然后重新开始慢开始阶段
- 快重传
快重传指的是当接受方收到顺序错误得数据时不接收数据,同时重复发起对于之前数据的确认,发动到第三次,发送方得知自己的一部分数据再发送中丢失,立即发起重传,不需要等待下一次发送信息时一起发送过去.,且重传时触发和拥塞一样得情况,进入快恢复阶段
途中M3丢失 ,接收方不接受M4和M5 ,而是不断发送确认M2得报文,三次之后,发送方重传M3的数据
-
快恢复
快恢复就是再发生拥塞和重传时,窗口经历了拥塞避免阶段,然后进入快恢复阶段,和拥塞避免一样都是每次加一,这样能提高恢复速度,像老版本(Tahoe)中需要重新经历慢开始
如何理解超时重传机制?
下面的文章讲的很全面:
(29条消息) TCP/IP协议栈:TCP超时重传机制_rtoax的博客-CSDN博客