UDP与TCP的对比

2023-11-14

1、报头
(1)TCP协议报头
TCP指传输控制协议,其报头格式如下:
在这里插入图片描述
1)源/目的端口号:表示数据是从哪个进程来,到哪个进程去。
2)32位序号/32确认号:用于可靠传输。
3)4位TCP报头长度:表示该TCP头部有多少个32位bit(有多少个4字节),所以TCP头部最大长度是15*4=60。
4)6位标志位:TCP协议中的六个标志分别是,URG、ACK、PSH、RST、SYN、FIN。
A、UGR(紧急):UGR=1表示紧急指针字段有效。它告诉系统此报文段有紧急数据,应当尽快传送。从报文段的开头,到紧急指针指向的地方就是紧急数据。
B、ACK(确认):ACK=1时,确认号字段才有效。
C、PSH(推送):让对方立即收到响应。与URG的区别就是URG中的紧急数据不经过缓冲区就直接上交给上层逻辑,而PSH还是要从缓冲区上交,只是不用等到缓冲区满了才上交。
D、RST(复位):RST=1时,表明TCP链接中出现严重差错,必须释放链接,然后再重新链接。以下几种场景中会使用RST报文(访问不存在的端口。异常终止一个链接,一般情况下是发送FIN,因为在所有排队数据都以发送之后才发送FIN,但是也有可能发送一个RST来异常释放连接。检测半打开的链接,即一端关闭,另一端不知道,这时会发送一个RST进行监测。当长时间不用连接,连接断开之后,再次访问的时候会发送RST)。
E、SYN(同步):在链接建立时用来同步序号。当SYN=1,ACK=0时表示请求报文。SYN=1,ACK=1表示链接接受。因此SYN=1表示一个链接请求或链接接受报文。
F、FIN(终止):用来释放一个链接。
5)16位窗口大小:表示数据传输的最大长度。
6)16位校验和:发送端填充,CRC检验,接收端校验不通过,则认为数据有问题。此处的校验和不光包含TCP首部,也包含TCP数据部分。
7)16紧急指针:标识哪部分数据是紧急数据。
8)40字节头部选项:存放一个窗口扩大因子等等信息。

(2)UDP协议报头
UDP指用户数据报协议,其报头格式如下:
在这里插入图片描述

2、TCP的优缺点
(1)TCP的优点:
TCP的优点是:可靠、稳定。它体现在TCP在传递数据之前,会有三次握手来建立连接;在数据传递时,采用校验和、序列号、确认应答、超时重发、流量控制、拥塞控制,为了提高性能,还采用了滑动窗口、延迟应答和捎带应答等机制;在数据传完后,会断开连接以节约系统资源。

(2)TCP的缺点:
TCP的缺点:运行速度慢,效率低,占用系统资源多,易被攻击。因为TCP在传递数据之前,要先建立连接,这会消耗时间;在数据传递时,确认机制、重传机制、拥塞控制机制等都会消耗大量的时间,而且要在每台设备上维护所有的传输连接,每个连接都会占用系统的CPU、内存等资源;TCP有确认机制、三次握手机制,这导致TCP容易受到DOS、DDOS、CC等攻击。收到STN洪水攻击,是因为使用 TCP的时候服务器端需要listen,这时需要设置backlog。

3、UDP的优缺点
(1)UDP的优点:运行速度较快,比TCP安全。
1)运行速度快,因为 UDP连接没有TCP的三次握手、确认应答、超时重发、流量控制、拥塞控制等机制,而且UDP是一个无状态的传输协议,所以它在传递数据时非常快。
2)较安全,因为没有TCP的那些机制,UDP较TCP被攻击者利用的漏洞就会少一些。但UDP也是无法避免攻击的,比如:UDP Flood攻击等。
(2)UDP的缺点:不可靠,不稳定。
因为UDP没有TCP那些可靠的机制,在数据传递时,如果网络质量不好,就会很容易丢包。

4、TCP和UDP的特点
(1)TCP的特点
TCP协议是一种有连接、可靠的、面向字节流、相对比较慢、点对点的传输层协议。TCP协议适用于对可靠性要求比较高的场合。
(2)UDP的特点
UDP协议是一种无连接,不可靠、面向数据报、速度比较快、可实现一对一,多对一的传输层协议。UDP协议适用于对实时性有要求的场合。因为UDP不保证可靠性,所以UDP也没有重传机制,也没有拥塞机制,它只是尽最大努力交付数据。

5、TCP保证数据可靠性和提高性能的机制
(1)确认应答(ACK)机制
TCP将每个字节的数据都进行了编号,即为序列号。每一个ACK都带有对应的确认序列号,意思是告诉发送者收到了哪些数据,下次从哪里开始发送。

(2)超时重传机制
1)超时重传机制的工作过程
主机A发送数据给B之后,可能因为网络拥堵等问题,数据无法到达主机B。如果主机A在一个特定时间间隔内没有收到B发来的确认应答,就会进行重发。但是,主机A未收到B发来的确认应答,也可能是因为ACK丢失了,因此主机B会收到很多重复数据。那么TCP协议需要能够识别出哪些包是重复的,并且把重复的丢弃掉,这时候可以利用序列号就可以很容易做到去重的效果。
2)如何确定超时时间?
最理想的情况下找到一个最小的时间,保证“确认应答”一定能在这个时间内返回。但是,这个时间的长短随着网络环境的不同是有差异的,如果超时时间设的太长会影响整体的重传效率;如果超时时间设得太短,有可能会频繁发送重复的包。
TCP为了保证无论在任何环境下都能比较高性能的通信,因此会动态计算这个最大超时时间。Linux中超时以500ms为一个单位进行控制,每次判定超时重发的超时时间都是500ms的整数倍。如果重发一次之后仍然得不到应答,等待2500ms后进行重传;如果仍然得不到应答,等待4500ms再进行重传,以此类推,以指数形式递增。累计到一定的重传次数,TCP认为网络或者对端主机出现异常,并强制关闭连接。

(3)滑动窗口
1)为什么需要滑动窗口?
前面讨论了确认应答策略,对每一个发送的数据段都要给一个ACK确认应答,收到ACK后再发送下一个数据段。这个做有一个比较大的缺点就是性能较差,尤其是数据往返的时间较长的时候。既然这样一发一收性能较低,那么如果一次发送多条数据,不是就可以将多个段的等待时间重叠在一起提高性能了吗?
2)工作过程
窗口大小指的是无须等待确认应答而可以继续发送数据的最大值,规定发送前4个段的时候,需要等待任何ACK直接发送。收到第一个ACK后,滑动窗口向后移动,继续发送第5个段的数据,以此类推。操作系统内核为了维护这个滑动窗口,需要开辟发送缓冲区来记录当前还有哪些数据没有应答,只有确认应答过的数据才能从缓冲区删掉,窗口越大网络吞吐率就越高。那么如果出现丢包,如何进行重传?
情况一:数据包已经抵达,ACK被丢了。
这种情况下,部分ACK丢了并不要紧,因为可以通过后续的ACK进行确认。
情况二:数据包直接丢了。
当某一段报文丢失之后,发送端会一直收到1001这样的ACK,就像是在提醒发送端“接收端想要的就是1001”一样。如果发送端主机连续三次收到了同样一个“1001”,就会将对应的数据1001-2000重新发送.这个时候接收端收到了1001之后,再次返回的ACK就是7001了,因为2001-7000接收端其实之前就已经收到了,被放到了接收端操作系统内核的接收缓冲区中。这种机制被称为“高速重发控制”,也称为“快重传”。

(4)流量控制
1)什么是流量控制?
接收端处理数据的速度是有限的,如果发送端发得太快,导致接收端的缓冲区被填满,这个时候如果发送端继续发送就会造成丢包,继而引起丢包重传等等一系列连锁反应。因此,TCP支持根据接收端的处理能力来决定发送端的发送速度,这个机制就叫做流量控制。
2)工作流程
接收端将自己可以接收的缓冲区大小放入TCP首部中的“窗口大小”字段,通过ACK端通知发送端。窗口大小字段越大,说明网络的吞吐量越高。接收端一旦发现自己的缓冲区快满了,就会将窗口大小设置成一个更小的值通知给发送端,发送端接收到这个窗口之后就会减慢自己的发送速度。如果接收端缓冲区满了就会将窗口置为0,这时发送方不再发送数据,但是需要定期发送一个窗口探测数据段,使接收端把窗口大小告诉发送端。
3)接收端如何把窗口大小告诉发送端?
在TCP首部中,有一个16位窗口字段就是用于存放窗口信息的。16位数字最大表示65535,那么TCP窗口最大就是65535字节么?实际上,TCP首部40字节选项中还包含了一个窗口扩大因子M,实际窗口大小是窗口字段的值左移M位。

(5)拥塞控制
1)拥塞控制的必要性
虽然TCP有了滑动窗口这个大杀器,能够高效可靠的发送大量数据,但是如果在刚开始阶段就发送大量的数据,仍然可能引发问题。因为网络上有很多的计算机,可能当前的网络状态就已经比较拥堵,在不清楚当前网络状态下贸然发送大量的数据,是很有可能雪上加霜的。
2)慢启动
TCP引入慢启动机制,先发少量的数据探探路,摸清当前的网络拥堵状态再决定按照多大的速度传输数据。此处引入一个概念——拥塞窗口,发送开始的时候,定义拥塞窗口大小为1。每次收到一个ACK应答拥塞窗口就加1,每次发送数据包的时候将拥塞窗口和接收端主机反馈的窗口大小做比较,取较小的值作为实际发送的窗口。
3)慢启动阀值
像上面这样的拥塞窗口增长速度是指数级别的。“慢启动”只是指初始时慢,但是增长速度非常快。为了不增长得那么快,因此不能使用拥塞窗口单纯的加倍。此处引入一个叫做慢启动的阀值,当拥塞窗口超过这个阀值的时候,不再按照指数方式增长,而是按照线性方式增长。 当TCP开始启动的时候,慢启动阀值等于窗口最大值,在每次超时重发的时候,慢启动阀值会变成原来的一半,同时拥塞窗口置回1。少量的丢包仅仅是触发超时重传,大量的丢包就会认为是网络拥塞。当TCP通信开始后,网络吞吐量会逐渐上升,随着网络发生拥堵,吞吐量会立刻下降。拥塞控制。归根结底是TCP协议想尽可能快的把数据传输给对方,但是又要避免给网络造成太大的压力的折中方案。(TCP拥塞控制这样的过程就好像热恋的感觉)

(6)延迟应答
如果接收端数据的主机立刻返回ACK应答,这个时候返回的窗口可能性比较小。假设接收端缓冲区为1M,一次收到了500k的数据,如果立刻应答,返回的窗口就是500k。但是实际上可能处理端处理的速度很快,10ms之内就把500k数据从缓冲区消费掉。在这种情况下,接收端处理还远没有达到自己的极限,即使窗口再放大一些,也能处理过来。如果接收端稍微等一会儿再应答,比如等待200ms再应答,那么这个时候返回的窗口大小就是1M。注意:窗口越大,网络吞吐量就越大,传输效率就越高,应在保证网络不拥塞的情况下尽量提高传输效率。那么,所有的包都可以延迟应答么?肯定不行,因为规定有数量限制,每隔N个包就应答一次;而且有时间限制,超过最大延迟时间就应答一次,具体的数量和时间依操作系统不同也有差异,一般N取2,超时时间取200ms。

(7)捎带应答
在延迟应答的基础上,很多情况下客户端服务器在应用层也是“一发一收”的,意味着客户端给服务器说了“how are you”,服务器也会给客户端会一个“Fine,thank 有”,那么这个时候ACK就可以搭顺风车和服务器回应的“Fine,thank you”一起回给客户端。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

UDP与TCP的对比 的相关文章

  • 使用.Net Core创建UDP套接字

    如何创建一个 UDP 套接字以非阻塞方式接收本地端点中的数据 我不知道数据来自的远程端口 我在 Linux 中使用 NET Core 我认为我可以使用 ReceiveAsync 但它似乎无法以这种方式工作 我这样解决了这个问题 static
  • 对 C# 中 UDP 协议的套接字感到困惑

    我刚刚开始通过各种 Google 搜索学习套接字 但在弄清楚如何在 C 中正确使用套接字时遇到一些问题 我需要一些帮助 我有一个测试应用程序 Windows 窗体 和一个不同的类 实际上在它自己的 dll 中 但这无关紧要 我有我的套接字代
  • 丢包纠错码 (UDP)

    我不知道要寻找什么 因为我从 纠错代码 中得到的只是与您不知道错误位置的情况相关的内容 因此 这些代码比我需要的要复杂得多 而且效率低下 在下文中 请注意位等于数据包 因为只有整个数据包可能会丢失 因此位类比非常适合 是否有 ECC 考虑到
  • Android udp 多播与以太网

    大家好 我正在开发一个使用 udp 多播的项目 我有一台服务器通过以太网电缆发送多播 udp 数据包 我花了几周的时间阅读有关 android 上多播的所有帖子 但我仍然无法在我的 Asus Transformer Tablet 4 1 上
  • Spark Scala UDP 在侦听端口上接收

    中提到的例子http spark apache org docs latest streaming programming guide html http spark apache org docs latest streaming pro
  • 如何使用 ZeroMQ 处理原始 UDP?

    我有一个客户 我无法更改其代码 但我想使用 重新 编写ZeroMQ插座 客户使用原始TCP和原始的UDP插座 我知道我可以使用ZMQ ROUTER RAW对于生的TCP插座 但是原始的怎么样 UDP数据流 ZeroMQ 中对 UDP 的支持
  • 数据报总是被完整接收吗?

    大多数数据报接收函数 例如c的recv或read java的DatagramPacket类或python的SocketServer 都包含找出接收数据量的可能性 c int amount recv sock buf n MSG WAITAL
  • 如何在多个程序中接收相同的udp流?

    我有一个封闭的第三方系统 它发送单播 UDP 流 MPEG TS 我想在同一台计算机上的两个不同程序中访问该流 我无法更改源上的任何内容 甚至无法更改 IP 或端口 除了编写自己的小程序来捕获流然后创建新流并重新发送这两个流之外 还有其他选
  • udp数据包被tcpdump捕获,但没有被套接字接收[关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我编写了一个 rawudp 程序 通过原始套接字发送 udp 数据包 按照网页http www tenouk com Module43a html h
  • C++ 反序列化通过 UDP 从 C# 应用程序发送的对象

    我有一个申请c 它连接到另一个应用程序 编写为c 通过UDP 我更喜欢高性能的解决方案 因为我希望测量事件客户端 某些处理服务器端和客户端处理完成的响应之间的时间 本质上是 往返延迟 我有一个 C 对象 例如 public class Pa
  • 接收来自 N 个客户端的响应,以回复通过 UDP 的广播请求

    我正在为特定类型的网络多媒体设备实现一种 IP 查找器 我想找出 LAN 中该类型的所有活动设备及其 IP 地址和其他详细信息 设备有自己的设备发现方式 其工作原理如下 客户端通过 UDP 通过 LAN 发送广播请求 目的端口号是固定的 作
  • 搜索所有网络上的设备

    我想实现一个代码 通过它我可以列出网络上连接的 upnp 兼容媒体渲染器设备 我用谷歌搜索了这个并找到了以下代码扭曲的网站 https twistedmatrix com documents current core howto udp h
  • 如何在QT中发送和接收UDP数据包

    我正在 QT 中编写一个小型应用程序 它通过本地网络发送广播 UDP 数据包 并等待来自网络上的一个或多个设备的 UDP 响应数据包 创建套接字并发送广播数据包 udpSocketSend new QUdpSocket this udpSo
  • VS2015:应用程序无法正确启动(0xc000007b)

    我在 Visual Studio 2015 上为 Windows 10 PC 编写了代码 该应用程序主要关注 UDP 通信 我使用 boost 库 它工作正常 但当我将代码文件夹移至 Windows 7 时 我收到错误 应用程序无法正确启动
  • netty 4.x.x 中的 UDP 广播

    我们需要使用 Netty 4 0 0 二进制文件通过 UDP 通道广播对象 Pojo 在 Netty 4 0 0 中 它允许我们仅使用 DatagramPacket 类来发送 UDP 数据包 此类仅接受 ByteBuf 作为参数 还有其他方
  • 对等网络应用程序的网络发现

    我希望有两个类 一个服务器类和一个客户端类 服务器类应该接收每个新客户端的 IP 地址和端口号并将它们存储在列表中 它应该为每个客户端提供已连接客户端及其 IP 地址的列表 然后 客户端可以使用 TCP 连接相互通信 问题是客户端不知道服务
  • 为什么我们可以将 sockaddr 转换为 sockaddr_in

    我明白为什么强制转换很有用sockaddr to sockaddr in 但我不明白这怎么可能 据我所知 它们的大小相同sockaddr in添加了sin zero使其大小相同 我想知道编译器如何知道从哪里获取信息sockaddr in如果
  • Python UDP广播不发送

    我正在尝试从 Python 程序到两个 LabView 程序进行 UDP 广播 我似乎无法发送广播 我不确定我的套接字初始化错误在哪里 广播似乎足够简单 据我所知 其他电脑没有收到任何数据 另外 我将来还需要这个程序来接收来自其他电脑的数据
  • 为什么SOCKS5需要通过UDP中继UDP?

    The SOCKS5 https en wikipedia org wiki SOCKS SOCKS5协议 描述为RFC1928 https www rfc editor org rfc rfc1928提供对 UDP 的支持 总而言之 希望
  • UDP接收和发送Matlab

    我目前正在努力从外部设备接收数据包 然后将数据发送到另一个设备 我有一个工作 Simulink 模型 但我不知道如何在 Matlab 中对其进行编码 Matlab 中 UDP 接收块的参数如下图所示UDP 接收参数 https i stac

随机推荐

  • Java获取JsonObject或JsonArray中的值

    1 导入Json格式化依赖
  • python——自定义函数

    一 概述 在编写脚本的过程中 对于要重复完成的工作 我们可以提取出来 将其编写为函数 在脚本中使用时 调用即可 在python中 函数必须先声明 然后才能在脚本中使用 使用函数时 只要按照函数定义形式向函数传递必须的参数 就可以调用函数完成
  • arm linux 蜂鸣器qt,Qt 程序中使用蜂鸣器 ioctl()

    在最近的项目中 由于使用的显示屏的触摸效果不是很好 有时触摸的力度小了 就没反应 用户的手指有挡住了按键 不能看到按键按下的时的效果 于是就提出了在按键触发效果时蜂鸣器就叫一下 在几经查找资料后 发现了ioctl 函数 能很好的控制I O设
  • pip安装库时报错:This error originates from a subprocess, and is likely not a problem with pip.

    前言 一 二 使用步骤 1 引入库 2 读入数据 总结 一 报错原因 安装库时出现以下报错 note This error originates from a subprocess and is likely not a problem w
  • spring boot 如何动态替换bean?

    替换Bean工具类 Component public class ApplicationContextUtil implements ApplicationContextAware private static ApplicationCon
  • 0-1背包

    文章作者 Yx Ac 文章来源 勇幸 Thinking http www ahathinking com 转载请注明 谢谢合作 四月份还没写 不能这么荒废了呀 赶紧水一篇吧 哈哈 前些日子回顾了DP的一些基础 就做一下整理吧 从0 1背包开
  • AIX使用RPM

    RPM安装 rpm ivh rpmname rpm 下载地址 aix的rpm下载地址一 AIX Toolbox for Linux Applications Downloads alpha aix的rpm下载地址二 找到自己版本的aix文件
  • 一个局外SEO人看360搜索

    最近国内搜索行业最大的事莫过于360搜索的推出 不少人在微博和博客留言里问我对360搜索有什么评论 作为一个以网络为生却无法感性体验国内互联网氛围的SEO 我其实对几个搜索引擎的厮杀 又有谁加入战局 各自使用了什么招数之类的事情不太关心 谁
  • 阿里巴巴 CTO 程立:开源是基础软件的源头!

    开源盛世下 无数企业拥抱开源技术并迅速向数字化转型 阿里巴巴便是国内走在前列的大型企业之一 7 月 28 日 阿里巴巴集团 CTO 程立在 2022 开放原子全球开源峰会上带来了 共建共享数字世界的根 主题演讲 从全球开源发展史下看阿里巴巴
  • 各种颜色代码

    网页颜色代码对照表 FFFFFF FFFFF0 FFFFE0 FFFF00 FFFAFA FFFAF0 FFFACD FFF8DC FFF68F FFF5EE FFF0F5 FFEFDB FFEFD5 FFEC8B FFEBCD FFE7B
  • I2C实验

    参考 I2C 总线协议详解 作者 一只青木呀 发布时间 2020 09 21 11 41 25 网址 https blog csdn net weixin 45309916 article details 108705297 目录 I2C
  • java构造器为什么不能被继承

    网上的解释都不太令人信服 所以写下这篇小文 构造器为什么不能被继承 这是由于构造器的特殊规定决定的 构造器的定义和普通方法相比 首先构造器不需要返回类型 其次构造器和类名相同 如果构造器可以被子类继承 其具备的地位有两种可能 一是作为子类的
  • Spring MVC 拦截器

    如何实现session共享问题 1 session都在内存里面存储的 只要有session对象我都分发出去 让其他应用都可以拿到 同步 缺点 只要有session对象都要广播出去 而且用户应用比较多了就会导致服务压力大 2 使用token
  • 【面试宝典】美团二面:Redis与MySQL双写一致性如何保证?

    前言 四月份的时候 有位好朋友去美团面试 他说 被问到Redis与MySQL双写一致性如何保证 这道题其实就是在问缓存和数据库在双写场景下 一致性是如何保证的 本文将跟大家一起来探讨如何回答这个问题 谈谈一致性 一致性就是数据保持一致 在分
  • VSCODE显示服务器输出的图片

    1 使用matplotlib库 import matplotlib pyplot as plt plt 用于显示图片 import matplotlib image as mpimg mpimg 用于读取图片 import numpy as
  • 一个 8 年 PhpStorm 使用者的配置分享

    我使用 PhpStorm 很长时间了 差不多 8 年 更准确地说是从 2012 年开始 那时候是第三版 那段时间发生了许多事 也发生了很大的改变 当然 你每天都会学到很多 这篇文章是我在 PhpStorm 的 8 年经验总结 我的这些最佳设
  • 交互式前景提取使用GrabCut算法(opencv_python学习)

    交互式前景提取使用GrabCut算法 cv grabCut 是 OpenCV 中用于执行 GrabCut 算法的函数 该函数可以将输入图像分割为前景和背景 下面是 cv grabCut 函数的基本语法 cv grabCut img mask
  • 模拟器显示图片,而真机不显示

    记录一个小bug 图片能在模拟器显示 但是在真机上显示不了 原因 图片的url有问题 真机有安全性限制 导致无法展示 1 首先 拿到图片的地址 将其拿到浏览器测试 可以看到浏览器显示的不安全 http www xxxxx com 9000
  • git最简单回滚并推送到远程

    1 代码回退 首先你要用git reflog查看你要回到的那个版本 然后用 git reset hard HEAD 回退到上个版本 git reset hard commit id 退到 进到 指定commit id 来把你的本地代码回到你
  • UDP与TCP的对比

    1 报头 1 TCP协议报头 TCP指传输控制协议 其报头格式如下 1 源 目的端口号 表示数据是从哪个进程来 到哪个进程去 2 32位序号 32确认号 用于可靠传输 3 4位TCP报头长度 表示该TCP头部有多少个32位bit 有多少个4