🍎一.UDP与TCP区别
🍒1.1UDP与TCP性质区别
在网络编程,操作系统给我们提供了一组API,叫做socket,可以视为应用层与传输层之间的通信桥梁,而传输层中有两个非常重要并且常用到的协议–TCP与UDP协议
●TCP:
TCP是一种面向有连接的传输层协议,它可以保证两端通信主机之间的通信可达能够正确处理在传输过程中丢包、传输顺序乱掉等异常情况。此外,TCP还能够有效利用带宽,缓解网络拥堵。然而,为了建立与断开连接,有时它需要至少7次的发包收包(三次握手,四次挥手),导致网络流量的浪费。此外,为了提高网络的利用率,TCP协议中定义了各种各样复杂的规范,因此不利于视频会议(音频、视频的数据量既定)等场合使用
●UDP:
UDP是一种面向无连接的传输层协议,不会关注对端是否真的收到了传送过去的数据,如果需要检查对端是否收到分组数据包,或者对端是否连接到网络,则需要在应用程序中实现。UDP常用于分组数据较少或多播、广播通信以及视频通信等多媒体领域
TCP与UDP区别:
1、TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接
2、TCP提供可靠的服务,也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保 证可靠交付
3、TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的 UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)
4、每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
5、TCP首部开销20字节;UDP的首部开销小,只有8个字节
6、TCP的逻辑通信信道是全双工的可靠信道,UDP则是全双工不可靠信道
TCP是:有连接,可靠传输,面向字节流,全双工
UDP是:无连接,不可靠传输,面向数据报,全双工
拓展:UDP与TCP之间的比较,UDP的传输效率高于TCP,但传输的文件较小和对可靠性要求不高时优先使用UDP。TCP是在保证可靠性的前提下,尽可能地去提升效率,但是还是有效率牺牲的,所以TCP的传输效率不如UDP,但是可靠性优于UDP。那么如何基于UDP实现可靠性?这个问题实际上在问你TCP,将TCP可靠性实现的思路在应用层复刻就可以了。当然传输层的协议不只有UDP与TCP,其他的如QUIC,游戏中经常使用
🍒1.2UDP与TCP应用区别
基于上述不同,UDP和TCP编程步骤也有些不同,如下:
TCP编程的服务器端一般步骤是:
1、创建一个socket,用函数socket();
2、设置socket属性,用函数setsockopt(); (可选)
3、绑定IP地址、端口等信息到socket上,用函数bind();
4、开启监听,用函数listen();
5、接收客户端上来的连接,用函数accept();
6、收发数据,用函数send()和recv(),或者read()和write();
7、关闭网络连接;
8、关闭监听;
TCP编程的客户端一般步骤是:
1、创建一个socket,用函数socket();
2、设置socket属性,用函数setsockopt();(可选)
3、绑定IP地址、端口等信息到socket上,用函数bind();(可选)
4、设置要连接的对方的IP地址和端口等属性;
5、连接服务器,用函数connect();
6、收发数据,用函数send()和recv(),或者read()和write();
7、关闭网络连接;
UDP编程的服务器端一般步骤是:
1、创建一个socket,用函数socket();
2、设置socket属性,用函数setsockopt();(可选)
3、绑定IP地址、端口等信息到socket上,用函数bind();
4、循环接收数据,用函数recvfrom();
5、关闭网络连接;
UDP编程的客户端一般步骤是:
1、创建一个socket,用函数socket();
2、设置socket属性,用函数setsockopt();(可选)
3、绑定IP地址、端口等信息到socket上,用函数bind();(可选)
4、设置对方的IP地址和端口等属性;
5、发送数据,用函数sendto();
6、关闭网络连接;
🍎二.UDP协议
🍒2.1什么是UDP协议
UDP是User Datagram Protocol的缩写,该协议不需要连接,不稳定传输,面向数据报,全双工,简单且高效,但是它的数据载荷较小,一般适用于以下场景:
●包总量较少的通信(DNS、SNMP等)
●视频、音频等多媒体通信(即时通信)
●限定于LAN等特定网络中的应用通信
●广播通信(广播、多播)
🍒2.2UDP协议格式
UDP协议的格式:
●源端口号(16位):就是操作系统自动给客户端分配的端口号
●目的端口号(16位):服务器端口号
●报文长度(16位):因为报文长度是2字节,所只可以传输0~65535大小的(64k)文件,当我们需要传输比较大的文件的时候UDP协议就会规定将文件拆分分为多个数据报进行传输,接收方就会将这些拆分的文件进行组装成完整的数据
●校验和(16位):是来判断网络传输的这个数据是否是正确的,因为网络传输的数据本质就是光信号和电信号,但是在外界作用的干扰下,如磁场,电磁场之类的情况下会导致数据会发生改变.
校验和的校验方法可以计算传输数据的个数与接收数据的个数是否一致,还可以根据数据的内容进行校验
●数据部分:完整的应用层的数据
●传输层的数据通常叫做:段–“segment”
●网络层的数据通常叫做:包/报–“packet”
●数据链路层数据通常叫做:帧–“frame”
🍎三.TCP协议
🍒3.1TCP协议格式
TCP协议相比于UDP协议要复杂一些,TCP需要连接,传输是可靠的,面向字节流,全双工。
TCP协议格式:
TCP这里的源端口号与目的端口号的意思与UDP完全一样,表示发送方与接收方的端口号。校验和的作用与UDP也是一样的,但是TCP的校验和功能不能关闭,而UDP可以关闭。
数据偏移,表示TCP数据起始处与TCP报文起始处之间的距离,其实就是TCP首部报头长度了,一共4比特,能表示0-15,单位为4字节,也就是说能表示TCP报头长度为0-60字节,基本上完全够用了,就算有一天不够用了,数据偏移后面还有6比特备用。
选项可有可无也可以有多个,可能包括“窗口扩大因子”、“时间戳”等选项。长度可变,最长可达 40 字节,当没有使用选项时,TCP 首部长度是 20 字节。填充是为了保证选项为32比特的整数倍。
控制位,字段长为8比特,每一位从左至右分别为CWR、ECE、URG、ACK、PSH、RST、SYN、FIN。
●CWR(Congestion Window Reduced)
CWR标志, 与后面的ECE标志都用于IP首部的ECN字段。ECE标志为1时,则通知对方已将拥塞窗口缩小
●ECE(ECN-Echo)
ECE标志, 表示ECN-Echo。置为1会通知通信对方,从对方到这边的网络有拥塞。在收到数据包的IP首部中ECN为1时将TCP首部中的ECE设置为1
●URG(Urgent Flag)
该位为1时,表示包中有需要紧急处理的数据。对于需要紧急处理的数据,会在后面的紧急指针中再进行解释
●ACK(Acknowledgement Flag)
该位为1时,确认应答的字段变为有效。TCP规定除了最初建立连接时的SYN包之外该位必须设置为1
●PSH(Push Flag)
该位为1时,表示需要将受到的数据立刻传给上层应用协议。PSH为0时,则不需要立即传而是先进行缓存
●RST(Reset Flag)
该位为1时表示TCP连接中出现异常必须强制断开连接。例如,一个没有被使用的端口即使发来连接请求,也无法进行通信。此时就可以返回一个RST设置为1的包。此外,程序宕掉或切断电源等原因导致主机重启的情况下,由于所有的连接信息将全部被初始化,所以原有的TCP通信也将不能继续进行。这种情况下,如果通信对方发送一个设置为1的RST包,就会使通信强制断开连接
●SYN(Synchronize Flag)
用于建立连接。SYN为1表示希望建立连接,并在其序列号的字段进行序列号初始值的设定(Synchronize本身有同步的意思。也就意味着建立连接的双方,序列号和确认应答号要保持同步。)
●FIN(Fin Flag)
该位为1时,表示今后不会再有数据发送,希望断开连接。当通信结束希望断开连接时,通信双方的主机之间就可以相互交换FIN位置为1的TCP段。每个主机又对对方的FIN包进行确认应答以后就可以断开连接。不过,主机收到FIN设置为1的TCP段以后不必马上回复一个FIN包,而是可以等到缓冲区中的所有数据都因已成功发送而被自动删除之后再发。
TCP数据段是可变的,可以简单的理解数据载荷没有限制
🍒3.2确定应答
保证数据可靠传输的第一关就是确认应答,我们知道可靠性的核心就是发送方知道发送数据有没有被接收方收到,确认应答机制是实现可靠性的核心机制。
确认应答的关键就是发送方发送数据给接收方后,接收方会自动返回一个响应表示收到数据了
比如,你和你的女神聊天说要请她吃麻辣烫,当你看到她的回复的时候,你就知道消息她收到了
当我们进行多次发送请求时,会遇到发送信息和应答信息不对应,容易产生乌龙
如下:
为了解决这个问题,我们就引入了序号和确认序号,这样就避免了乌龙
实际中的TCP传输中,是针对每一个字节进行编号,比如传输数据的序号是1,发送了1000个字节的数据,那么接收方收到数据后会返回一个1001,表示1001之前的数据以及全部收到了
实际中的TCP传输中,是针对每一个字节进行编号,比如传输数据的序号是1,发送了1000个字节的数据,那么接收方收到数据后会返回一个1001,表示1001之前的数据以及全部收到了
🍒3.3超时重传
主机A发送数据给B之后,可能因为网络拥堵等原因,数据无法到达主机B;如果主机A在一个特定时间间隔内没有收到B发来的确认应答,就会进行重发
还有另一种情况,当我A已经所发送的信息已经成功了,但是B回复我我们的ACK却丢失了,而A不知道A所发送的信息是否发送成功了,就会触发超时重传,所以A会一直发送信息等待B的回答(例如A重复发送向B借钱的信息就会产生一些不必要的麻烦),所以TCP内部会有一个去重操作
**去重操作:**接收方会先把发送过来的数据放到操作系统内核的"接收缓冲区"中,接收缓冲区可以视为一个内存空间,这个内存空间也可以视为一个阻塞队列,当接收到的数据,TCP会现根据序号来检查内存缓冲区是否已经存在了,如果存在就直接丢弃,如果不存在就放进去,用来保证调用的socket.api拿到的这个数据一定不是重复的
超时重传一定会成功码?当然不会!
如果我们遇到网络抖动一下之后,这个时候重传还是可以解决的,但是我们遇到网路断开,想要恢复就没有那么容易了,所以在这种情况下我们重传不会一直进行下去,当TCP连续重传都没有接收到回馈的ACK后,TCP的传输就只能放弃了,重传的时间并不是固定的,传输的间隔时间会根据每次传输的数次逐渐变大
操作系统具体传输多少次失败放弃?
操作系统具体每次重新传输时间增加多少?
一些一般我们是可以根据机制来进行配置的
基于上述这两个机制,TCP的可靠徐就得到了有效的保证