精华内容
参与话题
问答
  • 本文转自... 很早就计划写篇关于UDP的文章,尽管UDP协议远没TCP协议那么庞大、复杂,但是,要想将UDP描述清楚,用好UDP却要比TCP难不少,于是文章从下笔写,到最终写成,...
    展开全文
  • 转载一篇文章,解释了其中的原因: http://blog.chinaunix.net/u/553/showart_179794.html<br />  路径最大传输单元 (PMTU) 黑洞路由器 ZT路径最大传输单元 (PMTU) 黑洞路由器 数据包在路由器上的...

    转载一篇文章,解释了其中的原因:

    http://blog.chinaunix.net/u/553/showart_179794.html

     

    路径最大传输单元 (PMTU) 黑洞路由器 ZT

    路径最大传输单元 (PMTU) 黑洞路由器 数据包在路由器上的分片

    简介

    Internet 协议 (IP) 是针对由以太网、帧中继等多种网络技术构成的网络的应用而设计的。每种网络技术都有不同的最大传输单元 (MTU),即其能发送的帧的最大大小。IP MTU 就是所能发送的 IP 包的最大大小。以以太网为例,以太网的 MTU 为 1526 字节。减去报头和报尾的大小(共 26 字节),以太网的 IP MTU 为 1500 字节。

    为了适应各种网络技术不同的 IP MTU,IP 允许路由器将数据包进行分段。例如,如果数据包的大小超过了转发它的链路所允许的范围,则 IP 路由器会对数据包的有效负载进行分段,然后作为一个个的 IP 包(称为分段)进行发送。

    虽然 IP 的这个特性考虑了网络层的独立性,但它也会长时间占用处理器并占用大量内存,进而对 IP 路由器的性能产生实质性的影响。因此,包括 Internet 在内的现代 IP 网络都通过以下方法避免由路由器对 IP 包进行分段:

    发送基于 UDP 的通信时,将 UDP 消息的最大大小设置为足够小,以防止 IP 路由器进行分段。

    发送基于 TCP 的通信时,将 IP 报头中的“不分段”(DF) 标记设置为 1,阻止 IP 路由器对 TCP 数据段进行分段。

    当 TCP 对等方建立 TCP 连接时,它们会交换各自的 TCP 最大段大小 (MSS) 值。TCP 对等方会使用这两个 MSS 值中的较小值来建立 TCP 连接。以前,主机的 MSS 值是 MTU 减去用于 IP 和 TCP 报头的 40 字节。但是,为了支持额外的 TCP 选项(如时间戳和可选确认),典型的 TCP 和 IP 报头可增至 52 字节或更多字节。

    当路由器必须将 IP 包分段但又因 DF 标记设置为 1 而不能分段时,路由器可采用以下任一种方式:

    发送符合 RFC 792 中最初定义的“ICMP Destination Unreachable-Fragmentation Needed and DF Set”消息,然后丢弃该包。

    原始消息格式中不包含有关转发失败的链路的 IP MTU 的信息。

    发送符合 RFC 1191 中重新定义的“ICMP Destination Unreachable-Fragmentation Needed and DF Set”消息,然后丢弃该包。此新消息格式包含一个 MTU 字段,可指出转发失败的链路的 IP MTU。

    RFC 1191 定义了路径 MTU (PMTU) 发现,它使得成对的 TCP 对等方能够动态地发现二者之间路径的 IP MTU,从而发现该路径的 TCP MSS。一旦收到符合 RFC 1191 定义的“Destination Unreachable-Fragmentation Needed and DF Set”消息,TCP 就会将该连接的 MSS 调整为指定 IP MTU 减去 TCP 和 IP 报头的大小。这样,在该 TCP 连接上发送的后续包就不会超过最大大小,无需分段即可在该路径上传输。

    直接丢弃包。

    直接丢弃需分段但 DF 标记设置为 1 的包的路由器称为 PMTU 黑洞路由器。

    检测 PMTU 黑洞路由器

    PMTU 黑洞路由器会给 TCP 连接带来问题。例如,Microsoft® Windows® XP 和 Windows Server™2003 中的 TCP/IP 协议默认情况下会使用 PMTU 发现。TCP 会发送 DF 标记设置为 1 的数据段,并且在需要时,会根据符合 RFC 1191 定义的“ICMP Destination Unreachable-Fragmentation Needed and DF Set”消息的回执(其中包含 IP MTU),更改 TCP MSS 值。

    在 TCP 三次握手期间交换的 TCP 数据段不会太大,因而不会被 PMTU 黑洞路由器丢弃。但是,一旦开始在连接上传输数据—假定基于协商的 MSS 确定的 PMTU 比实际 PMTU 大—TCP 数据段的大于实际 PMTU 的 IP 包就会被直接丢弃。

    例如,您可以用 FTP 命令行工具成功地与 FTP 服务器建立连接并登录。但是,当您试图下载或者上载文件时,中间的 PMTU 黑洞路由器就会丢弃达到最大大小的 TCP 数据段,从而导致错误和文件传输失败。

    您可以按照下面的语法使用 Ping 工具来检测 PMTU 黑洞路由器:

    Ping destinationfl ICMPEchoPayloadSize

    此处的 destination 可以是一个 IP 地址,也可以是一个可解析为 IP 地址的名称。

    -f 选项可将 DF 标记设置为 1。

    -l 选项指定 ICMP Echo 消息的有效负载的大小。

    ICMPEchoPayloadSize 是 ICMP Echo 消息的有效负载的字节数。

    要计算 ICMPEchoPayloadSize ,可用您想发送的 IP 包的大小减去 28。这是因为,IP 报头的大小为 20 字节,而 ICMP Echo 消息的 ICMP 报头的大小为 8 字节。下图显示了二者的关系。

    IP 包大小

    例如,要发送长度为 1500 字节的 ICMP Echo 消息,您应使用以下命令:

    ping destination –f –l 1472

    如果有 IP MTU 更小的中间链路,且路由器发送了“ICMP Destination Unreachable-Fragmentation Needed and DF Set”消息,则 Ping 工具会显示“Packet needs to be fragmented but DF set”消息。如果有 IP MTU 更小的中间链路,且 PMTU 黑洞路由器直接丢弃了包,则 Ping 工具会显示“Request timed out”消息。

    要找出包含 PMTU 黑洞路由器的路径的有效 IP MTU,请使用 Ping 工具,同时不断增大 Echo 消息的有效负载的大小。因为典型子网的最小 IP MTU 是 576 字节,因此开始时可将 ICMP Echo 消息的有效负载设置为 548 字节,然后每次递增 100 字节,直到找到有效 PMTU。

    例如,如果 ping 10.0.0.10 -f -l 972 命令显示“Reply from 10.0.0.10”,而命令 ping 10.0.0.10 -f -l 973 显示“Request timed out”,则 IP 地址为 10.0.0.10 的节点的有效 PMTU 为 1000 字节 (972+28)。

    PMTU 黑洞路由器的解决方案和工作方法

    以下的 PMTU 黑洞路由器的解决方案和工作方法按照从最简单的解决方案到最困难的工作方法的顺序排列。

    1. 配置中间路由器以支持路由器端 PMTU 发现

    解决专用 Intranet 中的 PMTU 黑洞路由器问题的最简单的方法,是将您的所有路由器配置为支持路由器端 RFC 1191,并支持发送 ICMP Destination Unreachable-Fragmentation Needed and DF Set 消息(其中带有转发失败的链路的 IP MTU)。这与将路由器配置为支持主机端 RFC 1191 是有区别的,后者的路由器会对自己的 TCP 连接使用 PMTU 发现。

    在 Internet 上进行通信时,通常不太可能将 Internet 路由器配置为支持路由器端 PMTU 发现。在这种情况下,您可以使用以下各节介绍的工作方法。

    2. 启用 PMTU 黑洞路由器检测

    基于性能方面的考虑,Windows 2000、Windows XP 和 Windows Server 2003 中默认关闭了 TCP/IP 的 PMTU 黑洞路由器检测。如无法将路由器配置为支持路由器端 RFC 1191,则可配置以下注册表设置:

    Setting: EnablePMTUBHDetect
    Key: HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/Tcpip/Parameters
    Value Type: REG_DWORD
    Value: 1

    因为此注册表条目在默认情况下不存在,所以您必须使用注册表编辑器工具添加此条目,然后重启 Windows 使设置生效。

    PMTU 黑洞路由器检测得到启用后,如果 TCP 数次重新传输某分段但仍未得到确认,则它会试图发送 DF 标记设置为 0 的分段。如果接收到对 DF 标记设置为 0 的分段的确认,则连接中后续分段的 MSS 将减小,且其 DF 标记会设置为 1。启用 PMTU 黑洞路由器检测会增加重新传输给定分段的最大次数,从而会影响整体性能。

    3. 确定最佳 IP MTU 并通过 MTU 注册表设置来设置该值

    启用 PMTU 黑洞路由器检测的替代方法,是根据本文前面部分的介绍使用 Ping 工具确定所有相关路径的 PMTU 值,然后使用注册表设置手动配置发送接口的 IP MTU。

    该方法通过不停发送 DF 标记设置为 1,大小又不会导致 PMTU 黑洞路由器将其直接丢弃的 IP 包来避开 PMTU 黑洞路由器。手动指定 IP MTU 意味着所有通信量(包括本地子网通信量和不包含 PMTU 黑洞路由器的路径上的通信量)都将使用较小的 IP MTU。

    确定有效的 PMTU 后,您可以通过以下步骤手动指定 TCP/IP 接口的 IP MTU:

    1.

    打开 Network Connections 文件夹,记下 LAN 连接的名称,如“Local Area Connection”。

    2.

    单击开始 ,单击“运行”,键入“regedit.exe”,然后单击“确定”。

    3.

    使用注册表编辑器工具的树图(左边窗格)打开如下键:HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control /Network/{4D36E972-E325-11CE-BFC1-08002BE10318}

    4.

    此键下面是与已安装的 LAN 连接相关联的全局唯一标识符 (GUID) 的一个或多个键。这些 GUID 键中的每一个都有一个 Connection 子键。打开每个 GUID /Connection 键,寻找值与第一步中记下的 LAN 连接的名称匹配的 Name 设置。

    5.

    如果找到包含与 LAN 连接匹配的 Name 设置的 GUID /Connection 键,请写下或记下该 GUID 值。

    6.

    使用注册表编辑器的树视图打开如下键:HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/Tcpip /Parameters/Interfaces/GUID

    7.

    右键单击树视图中的“GUID”键,指向“新建”,然后单击“双字节值”。

    8.

    在注册表编辑器工具的内容窗格(右窗格)中,为新注册表设置的值键入 MTU ,然后按 ENTER

    9.

    在内容窗格中,双击新的 MTU 设置,并在“编辑双字节值”对话框中选择“十进制”,然后在“数值数据”中键入有效 MTU 值。

    10.

    单击“确定”。关闭注册表编辑器工具。

    11.

    重新启动计算机使 MTU 设置生效。

    4. 禁用 PMTU 发现

    如果确定网络上基于 Windows 计算机的所有 LAN 接口的合适的 PMTU 值并进行配置不太可行,则可以使用最后一招:禁用 PMTU 发现。我们不推荐使用此方法,因为如果禁用 PMTU 发现,所有远程目的地的 IP MTU 都将设置为 576 字节,而这会影响性能。

    要关闭 PMTU 发现,请配置如下注册表设置:

    Setting: EnablePMTUDiscovery
    Key: HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/Tcpip/Parameters
    Value Type: REG_DWORD
    Value: 0

    因为此注册表条目在默认情况下不存在,所以您必须使用注册表编辑器工具添加此条目,然后重启 Windows 使设置生效。

    展开全文
  • 深入理解TCP、UDP协议及两者的区别

    万次阅读 多人点赞 2018-11-14 13:03:24
    一、TCP协议: 位于传输层, 提供可靠的字节流服务。所谓的字节流服务(Byte Stream Service) 是指, 为了方便传输, 将大块数据分割成以报文段(segment) 为单位的数据包进行管理。 而可靠的传输服务是指, 能够...

    GitHub:https://github.com/JDawnF

    一、TCP协议:

           位于传输层, 提供可靠的字节流服务。所谓的字节流服务(Byte Stream Service) 是指, 为了方便传输, 将大块数据分割成以报文段(segment) 为单位的数据包进行管理。 而可靠的传输服务是指, 能够把数据准确可靠地传给对方。 即TCP 协议为了更容易传送大数据才把数据分割, 而且 TCP 协议能够确认数据最终是否送达到对方。所以,TCP连接相当于两根管道(一个用于服务器到客户端,一个用于客户端到服务器),管道里面数据传输是通过字节码传输,传输是有序的,每个字节都是一个一个来传输。

    (1)、三次握手:握手过程中使用了 TCP 的标志(flag) —— SYN(synchronize) 和ACK(acknowledgement) 。

    • 第一次握手:建立连接时,客户端A发送SYN包(SYN=j)到服务器B,并进入SYN_SEND状态,等待服务器B确认。
    • 第二次握手:服务器B收到SYN包,必须确认客户A的SYN(ACK=j+1),同时自己也发送一个SYN包(SYN=k),即SYN+ACK包,此时服务器B进入SYN_RECV状态。
    • 第三次握手:客户端A收到服务器B的SYN+ACK包,向服务器B发送确认包ACK(ACK=k+1),此包发送完毕,完成三次握手。

    若在握手过程中某个阶段莫名中断, TCP 协议会再次以相同的顺序发送相同的数据包。
     (2)、四次挥手:由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这个原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。先进行关闭的一方将执行主动关闭,而另一方被动关闭。

    • 客户端A发送一个FIN,用来关闭客户A到服务器B的数据传送。
    • 服务器B收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。
    • 服务器B关闭与客户端A的连接,发送一个FIN给客户端A。
    • 客户端A发回ACK报文确认,并将确认序号设置为收到序号加1。

    三次握手和四次挥手:在TCP连接中,服务器端的SYN和ACK向客户端发送是一次性发送的,而在断开连接的过程中, B端向A
    端发送的ACK和FIN是分两次发送的。因为在B端接收到A端的FIN后, B端可能还有数据要传输,所以先发送ACK,等B端处理完自己的事情后就可以发送FIN断开连接了。

    (3)、深入理解TCP连接: 

    由于TCP是全双工的,因此在每一个方向都必须单独关闭。这原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个FIN只意味着这个方向上没有数据流动,一个TCP连接在接收到一个FIN后仍能发送数据。 首先进行关
    闭的一方将执行主动关闭,而另一方执行被动关闭。
    TCP协议的连接是全双工连接,一个TCP连接存在双向的读写通道。简单来说,是“先关读,再关写” ,总共需要4个阶段。以客户机发起关闭连接为例:1.服务器读通道关闭;2.客户端写通道关闭;3.客户端读通道关闭;4.服务器写通道关闭。
    关闭行为是在发起方数据发送完毕之后,给对方发出一个FIN(finish)数据段,直到接收到对方发送的FIN,且对方收到了接收确认的ACK之后,双方的数据通信完全结束,过程中每次都需要返回确认数据段ACK。

    (4)、TCP使用滑动窗口机制来进行流量控制。
    建立连接时,各端分配一个缓冲区用来存储接收的数据,并将缓冲区的尺寸发送给另一端。接收方发送的确认消息中包含了自己剩余的缓冲区尺寸。剩余缓冲区空间的数量叫做窗口。其实就是建立连接的双虎互相知道彼此剩余的缓冲区大小。

     (5)、拥塞控制

    拥塞控制:防止过多的数据注入到网路中,这样可以使网络中的路由器或链路不至于阻塞。拥塞控制是一个全局性的过程,和流量控制不同,流量控制是点对点的控制。

    1、慢开始:发送方维持一个叫做拥塞窗口cwnd(congestion window)的状态变量。拥塞窗口的大小取决于网络的拥塞程度,并且动态的变化。发送方让自己的发送窗口等于拥塞窗口,另外考虑到接收方的接收能力,发送窗口可能小于拥塞窗口。思路就是:不要一开始就发送大量的数据,先试探一下网络的拥塞程度,也就是说由小到大增加拥塞窗口的大小。

    为了防止cwnd增长过大引起网络拥塞,还需要设置一个慢开始门限ssthresh状态变量。 ssthresh的方法如下:
    当cwnd < ssthresh时,开始使用慢开始算法;当cwnd > ssthresh, 改用拥塞避免算法;当cwnd = ssthresh时,慢开始与拥塞算法任意。
     2.拥塞避免:

    拥塞避免算法让拥塞窗口缓慢增长,即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1,而不是加倍,这样拥塞窗口按照线性规律缓慢增长。无论是在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(其根据就是没有收到确认,虽然没有收到确认可能是其他原因的分组丢失,但是因为⽆法判定,所以都当作拥塞处理),就把慢开始门限设置为出现拥塞时的发送窗口的一半,然后把拥塞窗口设置为1,执行慢开始算法:

    此外,还有快速重传和快速恢复,停止-等待协议,回退N帧协议,选择重传协议等。 

    二、UDP协议:

    无连接协议,也称透明协议,也位于传输层。

    两者区别:

    1) TCP提供面向连接的传输,通信前要先建立连接(三次握手机制); UDP提供无连接的传输,通信前不需要建立连接。
    2) TCP提供可靠的传输(有序,无差错,不丢失,不重复); UDP提供不可靠的传输。
    3) TCP面向字节流的传输,因此它能将信息分割成组,并在接收端将其重组; UDP是面向数据报的传输,没有分组开销。
    4) TCP提供拥塞控制和流量控制机制; UDP不提供拥塞控制和流量控制机制。


    三、长连接和短连接

           HTTP的长连接和短连接本质上是TCP长连接和短连接。HTTP属于应用层协议,在传输层使用TCP协议,在网络层使用IP协议。 IP协议主要解决网络路由和寻址问题,TCP协议主要解决如何在IP层之上可靠地传递数据包,使得网络上接收端收到发送端所发出的所有包,并且顺序与发送顺序一致。TCP协议是可靠的、面向连接的。

    在HTTP/1.0中默认使用短连接。也就是说,客户端和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。当客户端浏览器访问的某个HTML或其他类型的Web页中包含有其他的Web资源(如JavaScript文件、图像文件、CSS文件等),每遇到这样一个Web资源,浏览器就会重新建立一个HTTP会话。

    而从HTTP/1.1起,默认使用长连接,用以保持连接特性。使用长连接的HTTP协议,会在响应头加入这行代码:

    Connection:keep-alive
    

    在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,客户端再次访问这个服务器时,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。实现长连接需要客户端和服务端都支持长连接。

    HTTP协议的长连接和短连接,实质上是TCP协议的长连接和短连接。

    https://www.cnblogs.com/gotodsp/p/6366163.html

    此外,如果想更进一步学习网络相关的知识,可以参照:https://blog.csdn.net/striveb/article/details/84062700

     

    觉得有收获的,可以来一波赞赏!

    展开全文
  • TCP 和 UDP 的区别

    万次阅读 多人点赞 2018-08-04 21:57:42
    UDP TCP TCP 的三次握手 TCP 四次挥手 累计确认 顺序问题和丢包问题 流量控制的问题 拥塞控制的问题 总结及面试问题 前言 前端的面试中经常问的 TCP 和 UDP 的区别,网上也有好多内容,比如 TCP 和 ...

    前言

    前端的面试中经常问的 TCP 和 UDP 的区别,网上也有好多内容,比如

    TCP 和 UDP 的区别

    • TCP 是面向连接的,UDP 是面向无连接的
    • UDP程序结构较简单
    • TCP 是面向字节流的,UDP 是基于数据报的
    • TCP 保证数据正确性,UDP 可能丢包
    • TCP 保证数据顺序,UDP 不保证

    之前也因为面试的原因了解过一下,但是面试官又问了为什么 TCP 是可靠传输,一下就露馅了,说不出来了,然后这两天就仔细了解了一下这方面的内容,还专门订阅了极客时间的趣谈网络协议,因此,这篇文章主要基于趣谈网络协议和自己的理解。

    1. UDP

    要想理解 TCP 和 UDP 的区别,首先要明白什么是 TCP,什么是 UDP

    TCP 和 UDP 是传输层的两个协议

    我们来看一下 UDP 的包头
    UDP 包头
    由上图可以看出,UDP 除了端口号,基本啥都没有了。如果没有这两个端口号,数据就不知道该发给哪个应用。

    所以 UDP 就像一个小孩子,特别简单,有如下三个特点

    UDP 的特点

    • 沟通简单,不需要大量的数据结构,处理逻辑和包头字段
    • 轻信他人。它不会建立连接,但是会监听这个地方,谁都可以传给它数据,它也可以传给任何人数据,甚至可以同时传给多个人数据。
    • 愣头青,做事不懂变通。不会根据网络的情况进行拥塞控制,无论是否丢包,它该怎么发还是怎么发

    因为 UDP 是"小孩子",所以处理的是一些没那么难的项目,并且就算失败的也能接收。基于这些特点的话,UDP 可以使用在如下场景中

    UDP 的主要应用场景

    • 需要资源少,网络情况稳定的内网,或者对于丢包不敏感的应用,比如 DHCP 就是基于 UDP 协议的。
    • 不需要一对一沟通,建立连接,而是可以广播的应用。因为它不面向连接,所以可以做到一对多,承担广播或者多播的协议。
    • 需要处理速度快,可以容忍丢包,但是即使网络拥塞,也毫不退缩,一往无前的时候

    基于 UDP 的几个例子

    • 直播。直播对实时性的要求比较高,宁可丢包,也不要卡顿的,所以很多直播应用都基于 UDP 实现了自己的视频传输协议
    • 实时游戏。游戏的特点也是实时性比较高,在这种情况下,采用自定义的可靠的 UDP 协议,自定义重传策略,能够把产生的延迟降到最低,减少网络问题对游戏造成的影响
    • 物联网。一方面,物联网领域中断资源少,很可能知识个很小的嵌入式系统,而维护 TCP 协议的代价太大了;另一方面,物联网对实时性的要求也特别高。比如 Google 旗下的 Nest 简历 Thread Group,推出了物联网通信协议 Thread,就是基于 UDP 协议的

    还有一些,但是写的太多了也记不住,所以主要记住这几个就够了

    2. TCP

    首先是 TCP 的包头格式
    TCP 包头

    TCP 的包头有哪些内容,分别有什么用

    • 首先,源端口和目标端口是不可少的。
    • 接下来是包的序号。主要是为了解决乱序问题。不编好号怎么知道哪个先来,哪个后到
    • 确认序号。发出去的包应该有确认,这样能知道对方是否收到,如果没收到就应该重新发送,这个解决的是不丢包的问题
    • 状态位。SYN 是发起一个链接,ACK 是回复,RST 是重新连接,FIN 是结束连接。因为 TCP 是面向连接的,因此需要双方维护连接的状态,这些状态位的包会引起双方的状态变更
    • 窗口大小,TCP 要做流量控制,需要通信双方各声明一个窗口,标识自己当前的处理能力。

    通过对 TCP 头的解析,我们知道要掌握 TCP 协议,应该重点关注以下问题:

    • 顺序问题
    • 丢包问题
    • 连接维护
    • 流量控制
    • 拥塞控制

    2.1 TCP 的三次握手

    所有的问题,首先都要建立连接,所以首先是连接维护的问题

    TCP 的建立连接称为三次握手,可以简单理解为下面这种情况

    A:您好,我是 A
    B:您好 A,我是 B
    A:您好 B

    至于为什么是三次握手我这里就不细讲了,可以看其他人的博客,总结的话就是通信双方全都有来有回

    对于 A 来说它发出请求,并收到了 B 的响应,对于 B 来说它响应了 A 的请求,并且也接收到了响应。

    TCP 的三次握手除了建立连接外,主要还是为了沟通 TCP 包的序号问题。

    A 告诉 B,我发起的包的序号是从哪个号开始的,B 同样也告诉 A,B 发起的 包的序号是从哪个号开始的。

    双方建立连接之后需要共同维护一个状态机,在建立连接的过程中,双方的状态变化时序图如下所示
    状态变化时序图
    这是网上经常见到的一张图,刚开始的时候,客户端和服务器都处于 CLOSED 状态,先是服务端主动监听某个端口,处于 LISTEN 状态。然后客户端主动发起连接 SYN,之后处于 SYN-SENT 状态。服务端接收了发起的连接,返回 SYN,并且 ACK ( 确认 ) 客户端的 SYN,之后处于 SYN-SENT 状态。客户端接收到服务端发送的 SYN 和 ACK 之后,发送 ACK 的 ACK,之后就处于 ESTAVLISHED 状态,因为它一发一收成功了。服务端收到 ACK 的 ACK 之后,也处于 ESTABLISHED 状态,因为它也一发一收了。

    2.2 TCP 四次挥手

    说完建立连接,再说下断开连接,也被称为四次挥手,可以简单理解如下

    A:B 啊,我不想玩了
    B:哦,你不想玩了啊,我知道了
    这个时候,只是 A 不想玩了,即不再发送数据,但是 B 可能还有未发送完的数据,所以需要等待 B 也主动关闭。
    B:A 啊,好吧,我也不玩了,拜拜
    A:好的,拜拜

    这样整个连接就关闭了,当然上面只是正常的状态,也有些非正常的状态(比如 A 说完不玩了,直接跑路,B 发起的结束得不到 A 的回答,不知道该怎么办或则 B 直接跑路 A 不知道该怎么办),TCP 协议专门设计了几个状态来处理这些非正常状态
    断开连接状态时序图
    断开的时候,当 A 说不玩了,就进入 FIN_WAIT_1 的状态,B 收到 A 不玩了的消息后,进入 CLOSE_WAIT 的状态。

    A 收到 B 说知道了,就进入 FIN_WAIT_2 的状态,如果 B 直接跑路,则 A 永远处与这个状态。TCP 协议里面并没有对这个状态的处理,但 Linux 有,可以调整 tcp_fin_timeout 这个参数,设置一个超时时间。

    如果 B 没有跑路,A 接收到 B 的不玩了请求之后,从 FIN_WAIT_2 状态结束,按说 A 可以跑路了,但是如果 B 没有接收到 A 跑路的 ACK 呢,就再也接收不到了,所以这时候 A 需要等待一段时间,因为如果 B 没接收到 A 的 ACK 的话会重新发送给 A,所以 A 的等待时间需要足够长。

    2.3 累计确认

    TCP 如何实现可靠传输?

    首先为了保证顺序性,每个包都有一个 ID。在建立连接的时候会商定起始 ID 是什么,然后按照 ID 一个个发送,为了保证不丢包,需要对发送的包都要进行应答,当然,这个应答不是一个一个来的,而是会应答某个之前的 ID,表示都收到了,这种模式成为累计应答累计确认

    为了记录所有发送的包和接收的包,TCP 需要发送端和接收端分别来缓存这些记录,发送端的缓存里是按照包的 ID 一个个排列,根据处理的情况分成四个部分

    • 发送并且确认的
    • 发送尚未确认的
    • 没有发送等待发送的
    • 没有发送并且暂时不会发送的

    这里的第三部分和第四部分就属于流量控制的内容

    在 TCP 里,接收端会给发送端报一个窗口大小,叫 Advertised window。这个窗口应该等于上面的第二部分加上第三部分,超过这个窗口,接收端做不过来,就不能发送了

    于是,发送端要保持下面的数据结构
    发送端数据结构
    对于接收端来讲,它的缓存里面的内容要简单一些

    • 接收并且确认过的
    • 还没接收,但是马上就能接收的
    • 还没接收,但也无法接收的

    对应的数据结构如下
    接收端的数据结构

    2.4 顺序问题和丢包问题

    结合上面的图看,在发送端,1、2、3 已发送并确认;4、5、6、7、8、9 都是发送了还没确认;10、11、12 是还没发出的;13、14、15 是接收方没有空间,不准备发的。

    在接收端来看,1、2、3、4、5 是已经完成 ACK 但是还没读取的;6、7 是等待接收的;8、9 是已经接收还没有 ACK 的。

    发送端和接收端当前的状态如下:

    • 1、2、3 没有问题,双方达成了一致
    • 4、5 接收方说 ACK 了,但是发送方还没收到
    • 6、7、8、9 肯定都发了,但是 8、9 已经到了,6、7 没到,出现了乱序,缓存着但是没办法 ACK。

    根据这个例子可以知道顺序问题和丢包问题都有可能存在,所以我们先来看确认与重传机制

    假设 4 的确认收到了,5 的 ACK 丢了,6、7 的数据包丢了,该怎么办?

    一种方法是超时重试,即对每一个发送了但是没有 ACK 的包设定一个定时器,超过了一定的事件就重新尝试。这个时间必须大于往返时间,但也不宜过长,否则超时时间变长,访问就变慢了。

    如果过一段时间,5、6、7 都超时了就会重新发送。接收方发现 5 原来接收过,于是丢弃 5;6 收到了,发送 ACK,要求下一个是 7,7 不幸又丢了。当 7 再次超时的时候,TCP 的策略是超时间隔加倍。每当遇到一次超时重传的时候,都会讲下一次超时时间间隔设为先前值的两倍。

    超时重传的机制是超时周期可能相对较长,是否有更快的方式呢?

    有一个快速重传的机制,即当接收方接收到一个序号大于期望的报文段时,就检测到了数据流之间的间隔,于是发送三个冗余的 ACK,客户端接收到之后,知道数据报丢失,于是重传丢失的报文段。

    例如,接收方发现 6、8、9 都接收了,但是 7 没来,所以肯定丢了,于是发送三个 6 的 ACK,要求下一个是 7。客户端接收到 3 个,就会发现 7 的确又丢了,不等超时,马上重发。

    2.5 流量控制的问题

    在流量控制的机制里面,在对于包的确认中,会携带一个窗口的大小

    简单的说一下就是接收端在发送 ACK 的时候会带上缓冲区的窗口大小,但是一般在窗口达到一定大小才会更新窗口,因为每次都更新的话,刚空下来就又被填满了

    2.6 拥塞控制的问题

    也是通过窗口的大小来控制的,但是检测网络满不满是个挺难的事情,所以 TCP 发送包经常被比喻成往谁管理灌水,所以拥塞控制就是在不堵塞,不丢包的情况下尽可能的发挥带宽。

    水管有粗细,网络有带宽,即每秒钟能发送多少数据;水管有长度,端到端有时延。理想状态下,水管里面的水 = 水管粗细 * 水管长度。对于网络上,通道的容量 = 带宽 * 往返时延。

    如果我们设置发送窗口,使得发送但未确认的包为通道的容量,就能撑满整个管道。

    如图所示,假设往返时间为 8 秒,去 4 秒,回 4 秒,每秒发送一个包,已经过去了 8 秒,则 8 个包都发出去了,其中前四个已经到达接收端,但是 ACK 还没返回,不能算发送成功,5-8 后四个包还在路上,还没被接收,这个时候,管道正好撑满,在发送端,已发送未确认的 8 个包,正好等于带宽,也即每秒发送一个包,也即每秒发送一个包,乘以来回时间 8 秒。

    如果在这个基础上调大窗口,使得单位时间可以发送更多的包,那么会出现接收端处理不过来,多出来的包会被丢弃,这个时候,我们可以增加一个缓存,但是缓存里面的包 4 秒内肯定达不到接收端课,它的缺点会增加时延,如果时延达到一定程度就会超时重传

    TCP 拥塞控制主要来避免两种现象,包丢失和超时重传,一旦出现了这些现象说明发送的太快了,要慢一点。

    具体的方法就是发送端慢启动,比如倒水,刚开始倒的很慢,渐渐变快。然后设置一个阈值,当超过这个值的时候就要慢下来

    慢下来还是在增长,这时候就可能水满则溢,出现拥塞,需要降低倒水的速度,等水慢慢渗下去。

    拥塞的一种表现是丢包,需要超时重传,这个时候,采用快速重传算法,将当前速度变为一半。所以速度还是在比较高的值,也没有一夜回到解放前。

    总结及面试问题

    TCP 和 UDP 的区别

    • TCP 是面向连接的,UDP 是面向无连接的
    • UDP程序结构较简单
    • TCP 是面向字节流的,UDP 是基于数据报的
    • TCP 保证数据正确性,UDP 可能丢包
    • TCP 保证数据顺序,UDP 不保证

    什么是面向连接,什么是面向无连接

    在互通之前,面向连接的协议会先建立连接,如 TCP 有三次握手,而 UDP 不会

    TCP 为什么是可靠连接

    • 通过 TCP 连接传输的数据无差错,不丢失,不重复,且按顺序到达。
    • TCP 报文头里面的序号能使 TCP 的数据按序到达
    • 报文头里面的确认序号能保证不丢包,累计确认及超时重传机制
    • TCP 拥有流量控制及拥塞控制的机制

    TCP 的顺序问题,丢包问题,流量控制都是通过滑动窗口来解决的
    拥塞控制时通过拥塞窗口来解决的

    展开全文
  • UDP协议

    万次阅读 多人点赞 2017-06-21 12:31:05
    UDP协议UDP协议简介UDP(User Datagram Protocol),用户数据报协议,是OSI(Open System Interconnection,开放式系统互联) 参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,IETF RFC 768...
  • Android 发送udp消息

    千次阅读 2019-03-14 09:43:32
    参考,感谢两位大哥的文章 ... ... udp很早就听说过,但是由于其是面向无连接的协议,因此一直很少用到。但是在一些即时通讯方面,由于对延时有较高的要求,因此还是会使用到。 1.Android...
  • 本文以实例方式介绍,UDP跨网段进行数据传输的方法。 1、网络拓扑图 网络拓扑图如下图所示,要求192.168.1.103的计算机与192.168.2.1的计算机进行数据通信,但此两台计算机不在同一个网段内。图中设有两个路由器...
  • 终于懂了TCP和UDP协议区别

    万次阅读 多人点赞 2020-03-26 12:03:28
    终于懂了TCP和UDP协议区别
  • UDP通信——通过UDP进行转发

    千次阅读 2019-05-16 01:02:07
    UDP通信——通过UDP通信进行数据转发 想象一下这样的应用场景:我要从设备A向设备B发送数据,B根据接收到的数据信息向设备C发送数据(当然不一定分别是3个不同的设备),如何用UDP通信实现呢? 可以由易到难的试验...
  • UDP

    千次阅读 2018-08-13 22:54:34
     用户数据保协议(User Datagram Protocol,UDP)是开放系统互联模型(Open System Interconnection,OSI)中传输层协议的一种,是一种保留消息边界的简单的面向数据报的协议。UDP不提供差错纠正、队列管理、重复...
  • 今天学了C#的UDP,实现了一个非常简单的UDP收发工具 这个工具的功能就是发送UDP报文和监听UDP报文。在左侧的文本框中输入文字,单击“发送数据”按钮发送UDP报文。如果这个时候点击了右边的“接收数据”...
  • UDP 消息发送与接收得简单实现

    千次阅读 2019-06-20 10:38:38
    不说UDP是什么了,没意思,直接上demo 测试demo时放在不同得类里面,先启动接收类,再启动发送类。 发送端代码 public static void main(String[] args){ DatagramSocket ds=null; DatagramPacket dpSend=...
  • 7. 传输层协议(TCP、UDP

    万次阅读 2020-09-07 01:54:58
    TCP(Transmission Control Protocol)传输控制协议; TCP报文结构; TCP三次握手; TCP重传机制; TCP四次挥手; TCP端口号; UDP(User Datagram Protocol)用户数据协议; UDP报文结构。
  • IP头、TCP头、UDP头详解以及定义

    万次阅读 多人点赞 2013-01-24 13:47:25
    一、MAC帧头定义 /*数据帧定义,头14个字节,尾4个字节*/ typedef struct _MAC_FRAME_HEADER {  char m_cDstMacAddress[6]; //目的mac地址  char m_cSrcMacAddress[6]; //源mac地址  short m_cType;...
  • TCP和UDP的区别和优缺点

    万次阅读 多人点赞 2017-08-06 20:32:16
    1、TCP与UDP区别总结: 1、TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接 2、TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;...
  • 使用UDP发送消息

    千次阅读 2018-04-25 16:29:28
    1.简介在osi(七层网络架构:应用层,表示层,会话层,传输层,网络层,数据链路层,物理层)中,TCP和UDP属于同一层即传输层,IP属于网络层。TCP在传输时,需要建立稳定可靠的连接(三次握手和四次挥手)。UDP则不...
  • 如何实现UDP通讯时的连续发送消息,目前我只实现发送一条消息就不能再发送,在网上搜找后说要使用多线程,但是我不会啊,请求高手指导》 Server: private void btRec_Click(object sender, EventArgs e) { /...
  • 基于udp的服务器消息转发(群发)

    千次阅读 2018-09-25 17:14:51
    就是客户端通过服务器转发消息给其他客户端 转载地址:http://medicine.iteye.com/blog/1912231
  • UDP理解及UDP的MATLAB实现 Matlab UDP

    千次阅读 2020-04-14 16:04:01
    UDP理解及UDP的MATLAB实现一、UDP通信方式理解1、什么是UDP2、TCP和UDP区别3、个人对UDP的理解二、UDP的MATLAB实现1、单窗口实现2、多窗口实现参考 一、UDP通信方式理解 1、什么是UDP UDP是User Datagram Protocol的...
  • TCP和UDP的最完整的区别

    万次阅读 多人点赞 2016-08-04 11:30:30
    TCP和UDP两种协议的比较汇总
  • 本人新手,正做一个UDP跨路由通信项目,遇如下问题:服务端(192.168.0.85)与路由器在同一网段,客户端(192.168.1.103)在该路由器组成的局域网内,现服务端可以接收到客户端发送的UDP包,但客户端无法收到服务端...
  • Udp消息发送接收示例

    千次阅读 2009-05-26 14:24:00
    在Java中发送和接收UDP消息需要使用到如下两个对象1、DatagramSocket,重要方法是send和receive2、DatagramPacket,重要方法是getLength(这个不是必须的)下面简单模拟一个服务端和一个客户端:首先运行服务端,...
  • socket实现UDP收发消息

    千次阅读 2018-04-03 00:17:58
    # 创建udp套接字 udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 设置接收方的地址和端口(根据具体情况更改) dest_addr = ("255.255.255.255", 8080) # 从键盘输入数据 sen....
  • Qt使用udp发送消息

    千次阅读 2014-02-19 13:42:02
    udp属于传输层内容。  以太网(Ethernet)数据帧的长度必须在46-1500字节之间,这是由以太网的物理特性决定的.这个1500字节被称为链路层的MTU(最大传输单元).但这并不是指链路层的长度被限制在1500字节,其实这个MTU指...
  • Netty之UDP协议开发

    万次阅读 热门讨论 2016-11-21 20:49:22
    UDP协议简介UDP是用户数据报协议(User Datagrame Protocol,UDP)的简称,主要作用是将网络数据流压缩成数据报的形式,提供面向事务的简单信息传送服务。
  • 1、UDP(User Data Protocol,用户数据报协议) (1) UDP是一个非连接的协议,传输数据之前源端和终端不建立连接,...在接收端,UDP把每个消息段放在队列中,应用程序每次从队列中读一个消息段。 (2) 由于传输数据
  • 网络协议 -- UDP协议(1)介绍

    万次阅读 多人点赞 2017-12-28 16:12:59
    一、什么是UDP协议? UDP是User Datagram Protocol的简称,中文名是用户数据报协议,是OSI参考模型中的传输层协议,它是一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。 UDP的正式规范是IETF RFC...
  • 1、同样的程序,直接udp方式,输入了ip,我可以向对方发送消息,对方向我发送没反应 2、从tcp方式切换为udp方式,对方可以向我发送消息,但我向对方发送对方就会一直接受,程序崩溃 3、我是用同一个socket进行udp...
  • UDP协议的详细解析

    万次阅读 多人点赞 2018-12-26 17:16:34
    UDP数据报 一、UDP的概述 二、UDP的首部格式 UDP校验
  • TCP与UDP区别详解

    千次阅读 多人点赞 2020-05-19 21:23:53
    TCP与UDP区别详解 计算机与其他网络设备相互通信,通信的双方在发送和接收数据包时必须基于相同的规则(例如:如何找到通信目标、如何发起通信、如何结束通信等规则都需要事先确定),我们将这种规则称为协议...

空空如也

1 2 3 4 5 ... 20
收藏数 423,517
精华内容 169,406
关键字:

udp消息无法通过路由器返回