4927 字
25 分钟
Tcp和udp

1.概述#

TCP 和 UDP 都是传输层协议,他们都属于TCP/IP协议族。

2.UDP#

① UDP概念#

UDP的全称是用户数据报协议(User Datagram Protocol),在网络中它与TCP协议一样用于处理数据包,是一种无连接的协议。在OSI模型中,在传输层,处于IP协议的上一层。UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。

② UDP特点#

UDP只在IP数据报之上增加了很少功能,即复用分用和差错检测功能。

UDP的主要特点:#

无连接、无拥塞控制、不保证可靠交付、面向报文的、首部开销小的协议

UDP是无连接的,减少开销和发送数据之前的时延。 知道对端的IP和端口号就直接进行传输,不需要建立连接;

UDP使用最大努力交付,即不保证可靠交付,没有任何安全机制,发送端发送数据报以后,如果因为网络故障该段无法发到对方,UDP协议层也不会给应用层返回任何错误信息;

UDP是面向报文的,适合一次性传输少量数据的网络应用,应用层交给UDP多长的报文,UDP原样发送,既不会拆分,也不会合并;

例如用UDP传输100个字节的数据:如果发送端一次发送100个字节,那么接收端也必须一次接收100个字节;而不能循环接收10次,每次接收10个字节。

UDP无拥塞控制,适合很多实时应用。 UDP首部开销小,8比特,TCP有20比特。

③ UDP首部#

UDP 头部包含了以下几个数据:

源/目的端口号:表示数据是从哪个进程来,到哪个进程去;

UDP长度:16位UDP长度,表示整个数据报(UDP首部+UDP数据)的最大容量,一个UDP报文最多就只能有64KB,如果需要使用UDP传输一个比较大的数据,就需要考虑进行拆包

校验和:校验和就是为了检查数据是否出错了(网络传输过程中,受到一些干扰,是容易导致传输的数据出错的)

UDP校验和使用了一个比较常见的CRC算法(循环冗余校验):把UDP报文中的每个字节都进行累加,和也放到一个两个字节的数字中(加的过程中如果溢出了就溢出),最终得到的结果就是校验和

发送方发送数据的时候,就先计算一个校验和,接收方接收的时候,按照同样的规则再算一次校验和,最后看一下两次校验和是不是一样的(这里出现问题的概率还是比较小的)

3.TCP#

① TCP概念#

TCP的全称是传输控制协议(Transmission Control Protocol),是一种面向连接的、可靠的、基于字节流的传输层通信协议。TCP 是面向连接的、可靠的流协议(流就是指不间断的数据结构)。

② TCP特点#

面向连接、点对点、可靠交付、提供全双工通信、面向字节流的协议 TCP是面向连接(虚连接)的传输层协议。TCP协议使用时必须先建立 TCP 连接。在传送数据完毕后,必须释放已经建立的 TCP 连接

每一条TCP连接只能有两个端点,每一条TCP连接只能是点对点的。

TCP提供可靠交付的服务,无差错、不丢失、不重复、按序到达。 (可靠有许、不丢不重)可靠传输就是数据传输过去之后,发送方知道数据发送的成功与否,如果失败会尝试再次发送

TCP提供全双工通信。 发送缓存:准备发送的数据或者已发送但尚未收到确认的数据。 接收缓存:按序到达但尚未被接受应用程序读取的数据或者不按序到达的数据。 TCP允许通信双方的应用进程在任何时候都能发送数据

TCP面向字节流。 TCP把应用程序交下来的数据看成仅仅是一连串的无结构的字节流。应用层交给TCP的报文,整个报文可能会被操作系统分组成多个的 TCP 报文,也就是一个完整的TCP报文被拆分成多个 TCP 报文进行传输,例如用TCP传输100个字节的数据:如果发送端一次发送100个字节,那么接收端可能会循环接收10次,每次接收10个字节

③TCP首部#

可靠传输原理:#

(1)确认应答机制(可靠机制)#

每次发送数据之后,通过收没收到回复报文来确定发送成功与否,这样传输就变得可靠了,回复的报文称之为”应答报文”,也称之为”ack报文”

接收方成功接收数据的话,会向发送方发送一个应答报文表示数据成功接收,应答报文中的标志位ACK就会被置为1(之前为0),表示数据成功接收了。并且应答报文中还会携带确认序号,意思是告诉发送者,我已经收到了哪些数据;下一次你从哪里开始发。

(2)超时重传机制(可靠机制)#

主机A发送数据给B之后,可能因为网络拥堵等原因,数据无法到达主机B;如果主机A在一个特定时间间隔内没有收到B发来的确认应答,就会进行重发; 但是,主机A未收到B发来的确认应答,也可能是因为ACK丢失了;因此主机B会收到很多重复数据。那么TCP协议需要用到序列号识别出那些包是重复的包,并且把重复的丢弃掉。 超时重传的时间间隔是会逐渐变大的(因为连续的超时重传是极小概率事件),如果重传一定次数之后仍然无法传输,就会尝试重置TCP连接(断开重连),如果还是连不上,此时就直接释放连接(彻底放弃)

(3)连接管理机制(可靠机制)#

在正常情况下,TCP要经过三次握手建立连接,四次挥手断开连接

三次握手图示:

ACK和SYN都是系统内核负责的,会在收到请求之后,立即就返回

(4)滑动窗口(效率机制)#

TCP希望能够在保证可靠性的前提下,尽可能的提高传输效率,因此可以使用滑动窗口来提升效率

滑动窗口:每次批量发送一波数据,然后再等一波ACK,再发一波数据。我们把每次批量发送的数据的量称之为”窗口大小”~~

注意:接收方是收到一个数据就发送一个ACK,而不是等所有数据都到了才统一发下一组;发送方也是收到一个ACK就继续发一条数据,而不是等所有ACK都到了才统一发下一组~~

白色窗口就表示哪些数据在等待确认,也就是在等待数据到达与接收应答报文这个过程准确无误的完成:

情况一:数据包已经抵达,ACK被丢了。

这种情况下,部分ACK丢了并不要紧,因为可以通过后续的ACK进行确认;

情况二:数据包就直接丢了。

当某一段报文段丢失之后,发送端会一直收到 1001 这样的ACK,就像是在提醒发送端 “我想要的是 1001” 一样

如果发送端主机连续三次收到了同样一个 “1001” 这样的应答,就会将对应的数据 1001 - 2000 重新发送;

这个时候接收端收到了 1001 之后,再次返回的ACK就是7001了(因为2001 - 7000)接收端其实之前就已经收到了

这种机制被称为 “快速重传机制”,它是搭配了滑动窗口机制的”超时重传”。

(5)流量控制(可靠机制)#

在滑动窗口的基础之上,对发送速率做出限制的机制,也就是限制发送方的窗口大小不要太大(要合适)

接收端处理数据的速度是有限的。如果发送端发的太快,导致接收端的缓冲区被打满,这个时候如果发送端继续发送,就会造成丢包,继而引起丢包重传等等一系列连锁反应。

接收方使用接收缓冲区的剩余空间大小,来作为发送方发送速率(窗口大小)的参考数值

接收方将自己可以接收的缓冲区大小放入 TCP 首部中的 “窗口大小” 字段,通过ACK通知发送方;

接收方一旦发现自己的缓冲区快满了,就会将窗口大小设置成一个更小的值通知给发送方;发送方接受到这个窗口之后,就会减慢自己的发送速度;

如果接收方缓冲区满了,就会将窗口置为0;这时发送方不再发送数据,但是需要定期发送一个窗口探测数据段,使接收方把窗口大小告诉发送方。

(6)拥塞控制(可靠机制)#

也在滑动窗口的基础之上,对发送速率做出限制的机制,也就是限制发送方的窗口大小不要太大(要合适)

TCP引入 慢启动 机制,先发少量的数据,探探路,摸清当前的网络拥堵状态,再决定按照多大的速度传输数据;

每次发送数据包的时候,将拥塞窗口和接收端主机反馈的窗口大小(也就是和流量控制)做比较,取较小的值作为实际发送的窗口

(7)延迟应答(效率机制)#

延迟应答的作用就是让窗口大小在不影响接收方与发送方的处理能力的前提下尽量的大一些

如果接收数据的主机立刻返回ACK应答,这时候返回的窗口可能比较小

假设接收端缓冲区为1M。一次收到了500K的数据;如果立刻应答,返回的窗口就是500K;但实际上可能处理端处理的速度很快,10ms之内就把500K数据从缓冲区消费掉了;在这种情况下,接收端处理还远没有达到自己的极限,即使窗口再放大一些,也能处理过来;如果接收端稍微等一会再应答,比如等待200ms再应答,那么这个时候返回的窗口大小就是1M;

一定要记得,窗口越大,网络吞吐量就越大,传输效率就越高。我们的目标是在保证网络不拥塞的情况下尽量提高传输效率;

那么所有的包都可以延迟应答么?肯定也不是:

数量限制:每隔N个包就应答一次;

时间限制:超过最大延迟时间就应答一次;

(8)捎带应答(效率机制)#

本来ACK是系统内核负责的,会在收到请求之后,立即就返回,但是由于延迟应答机制会稍微等一会返回,这一等正好业务上也要返回内容,此时内核就可以把两个报文合二为一

(9)面向字节流的”粘包问题”#

A应用程序,需要从接收缓冲区中读取收到的数据,由于是面向字节流的,A无法确定从哪到哪是一个完整的应用层数据报

想要解决”粘包问题”,只要定义应用层数据协议的时候,明确包和包之间的”边界”(比如约定使用;作为结束标记),就可以了

TCP异常情况#

1、程序崩溃:进程异常退出,操作系统会回收进程的资源,包括释放文件描述符表,这样的释放操作,就相当于调用了对应socket的close,执行close就会触发FIN报文,进一步开始四次挥手~~

2、正常关机:关机的时候,系统会强制结束所有的用户进程;之后的步骤与上述程序崩溃一样

3、主机掉电:非常突然,猝不及防的~~

掉电的是接收方:发送方是不知道对面挂了的,继续发数据(没有ack),之后触发超时重传,重传几次之后仍没有应答,尝试重置链接(也会失败,触发复位报文段RST),最后只能放弃连接

掉电的是发送方:此时接收方就等着,等一阵之后就会发送一个”心跳包”,如果对方不返回”心跳包”,就说明对方挂了

“心跳包”是周期性触发的,只是一个简单的不携带任何业务数据的包,存在的意义就是确认一下对方是否还在

4、网线断开:情况同主机掉电一样,只不过通信双方的主机都好着呢,这两端各自按照上述两种情况分别进行~~

TCP协议格式#

(1)源/目的端口号:表示数据是从哪个进程来,到哪个进程去;

(2)32位序号/32位确认号:32位序号针对请求数据进行的编号,32位确认序号针对应答报文(ACK报文)进行的编号。每一个ACK报文都带有对应的确认序列号,意思是告诉发送者,我已经收到了哪些数据;下一次你从哪里开始发。

32位序号:该条TCP数据所携带的起始序号。 32位确认序号:期望对方发送数据从哪一个序号开始发送。

(3)4位TCP报头长度:表示该TCP头部有多少个32位bit(有多少个4字节);所以TCP头部最大长度是15 * 4 = 60字节

TCP报头前20个字节是固定的,后面是留给选项的,选项可有可无(它是可变的),选项可以是0个字节,最多是40个字节(什么是选项不做讨论)

(4)6位保留位:现在虽然不用,先占个位置,以后可能会用,也就是留下的可扩展空间

(5)6个特殊标志位(6个比特位):

  • URG:紧急指针是否有效

  • ACK:在数据通信中,接收方发给发送方的一种传输类控制字符,表示发来的数据已确认接收无误。如果接收方成功的接收到数据,那么这一位会被置为1,也就是应答报文(ack报文)这一位置为1。 ACK是系统内核负责的,会在收到请求之后,立即就返回

  • PSH:提示接收端应用程序立刻从TCP缓冲区把数据读走

  • RST:对方要求重新建立连接;我们把携带RST标识的称为复位报文段

  • SYN:请求建立连接;我们把携带SYN标识的称为同步报文段;SYN这一位如果为1说明这是一个同步报文段(尝试和对方建立连接) SYN是系统内核负责的,会在收到请求之后,立即就返回

  • FIN:通知对方本端要关闭连接了,我们称携带FIN标识的为结束报文段;FIN这一位如果为1说明这是一个结束报文段(通知对方本端要关闭连接了) FIN是应用程序负责的(代码中主动调用close),何时返回取决于我们的代码

(6)16位窗口大小:存放当前接收方接收缓冲区的剩余大小,这个字段得是在ACK为1的时候(应答报文的时候)才有效,窗口大小是动态的(实时改变)

窗口大小最大不是64kb(也就是16位的最大值),选项中有窗口大小扩展因子来表示更大的值

(7)16位校验和:校验和就是为了检查数据是否出错了(网络传输过程中,受到一些干扰,是容易导致传输的数据出错的),此处的检验和不光包含TCP首部,也包含TCP数据部分。

TCP校验和使用了一个比较常见的CRC算法(循环冗余校验):把TCP报文中的每个字节都进行累加,和也放到一个两个字节的数字中(加的过程中如果溢出了就溢出),最终得到的结果就是校验和 发送方发送数据的时候,就先计算一个校验和,接收方接收的时候,按照同样的规则再算一次校验和,最后看一下两次校验和是不是一样的(这里出现问题的概率还是比较小的)

(8)16位紧急指针:标识哪部分数据是紧急数据;

(9)MSS:最大报文段长度(MAX Segmet Size) 在三次握手过程中,双方协商MSS的大小,取两者的最小值。

  • 为什么要协商最大报文段长度?

防止报文过大,在网络当中传输的时候,数据丢失导致重传。(为了不让其频繁的重传)

MSS的大小会受到数据链路层MTU的影响

MTU:最大传输单元,是网卡在传输数据帧的时候的一个限制值,这个限制值是取决于网络传输设备的电气特性。(我们可以使用ifconfig命令中看到MTU的大小,一般在网络中传输的基本都是1500字节)

MSS + tcpHeader + ipHeader <= MTU,这是一个特性。

4.TCP和UDP的区别#

UDPTCP
是否连接无连接面向连接
是否可靠不可靠传输,不使用流量控制和拥塞控制可靠传输(数据顺序和正确性),使用流量控制和拥塞控制
连接对象个数支持一对一,一对多,多对一和多对多交互通信只能是一对一通信
传输方式面向报文面向字节流
首部开销首部开销小,仅8字节首部最小20字节,最大60字节
适用场景适用于实时应用,例如视频会议、直播适用于要求可靠传输的应用,例如文件传输

5.TCP和UDP的使用场景#

TCP应用场景: 效率要求相对低,但对准确性要求相对高的场景。因为传输中需要对数据确认、重发、排序等操作,相比之下效率没有UDP高。例如:文件传输(准确高要求高、但是速度可以相对慢)、接受邮件、远程登录。 UDP应用场景: 效率要求相对高,对准确性要求相对低的场景。例如:QQ聊天、在线视频、网络语音电话(即时通讯,速度要求高,但是出现偶尔断续不是太大问题,并且此处完全不可以使用重发机制)、广播通信(广播、多播)。

Tcp和udp
https://fuwari.cbba.top/posts/tcp和udp/
作者
Chen_Feng
发布于
2023-03-05
许可协议
CC BY-NC-SA 4.0