精华内容
参与话题
问答
  • 游戏程序 平台类型: 程序设计: ... 概述 PVP系统俨然成为现在新手游的上线标配,手游Pvp系统体验是否优秀,很大程度上决定了游戏的品质。从最近半年上线的新手游来看,越来越多的游戏把核心玩法重心已经放在...
    游戏程序
    平台类型:  
    程序设计:  
    编程语言:  
    引擎/SDK:  
      概述

      PVP系统俨然成为现在新手游的上线标配,手游Pvp系统体验是否优秀,很大程度上决定了游戏的品质。从最近半年上线的新手游来看,越来越多的游戏把核心玩法重心已经放在pvp多人游戏中,手游朝着更重度、多人实时交互的方向发展。本文主要分为两部分介绍pvp系统,前半部分主要介绍手游后台Pvp的同步方案介绍,第二部分主要介绍天天飞车和现在正在开发当中新赛车手游pvp网络同步方案。

      同步机制的一致性问题

      同步问题的本质是一致性的问题,在同一局多人游戏的过程中,玩家A看到玩家B的状态,应该跟玩家B自身看到自己的状态相一致。延迟是造成不一致的本质原因,假设理想情况下双方的网络时延都为0,那两者应该是同步的,但是在现实情况中,往往是不可能的,本文讨论的同步机制,就是为了解决一致性问题而产生的,对于不同的游戏类型,不同的团队技术积累,可以根据自身情况采取不同的同步机制技术方案。

      根据网络的拓扑结构区分,网络同步通信可以是client- client直连p2p通信,也可以是client-server-client服务器转发通信,client中选取一台当作server转发client间通信。本文以常见的手游后台同步方案机制来区分,分为帧同步方案,位置状态信息同步方案进行阐述。

      1.帧同步

      原理

      设存在玩家A、B、C,服务器Server设为S,假设玩家A、B、C是一个状态机,一开始A、B、C都处于状态S1,这时候服务器S给A、B、C相同的输入I,此时A、B、C经过本地的运算,得到同一个状态S2。 在这短暂的时刻,可以理解成所有玩家从状态S1同步到状态S2,三个玩家便达到同步的目的。只要状态机函数模型Fun,初始S1,输入I是确定的,那么三个玩家得到的结果S2肯定也是确定的。

    <ignore_js_op>

      如图中所示,玩家A、B、C在T1、T2、T3时刻都会收到服务器发送过来的输入,从而变成相同的状态S1,S2,S3,达到同步的目的。可以想象成这就是个回合制的游戏,每个T1、T2、T3间隔是一个回合,玩家在回合结束的时候,状态是一致同步的。那对于我们游戏来说,服务器的输入可以是玩家在这回合的操作序列,可以是状态信息,都可以,取决于客户端游戏方案的设计。只要这输入到达任何一个客户端那里,能把这数据模拟成真实的游戏场景就可以了。此时您可能会有这样的疑问,如果帧同步比作成一个回合制游戏的话,那会不会出现一卡一卡的情况出现呢。其实是不会的,一般游戏的帧数为30-60帧玩家认为是流畅的,对于帧同步来说,我们把里面的每一次输入的时间间隔足够短,人眼的反应是可以被欺骗的,就好像电影放映一样,一张张连续的图片快速播放,人眼就会感觉是连续发生的,同理帧同步虽然就像是一个回合制游戏,但是只要回合的时间足够短,玩家看起来就像是连续的一样。通常情况下,我们把这个回合称为逻辑帧,逻辑帧的设定可以根据游戏类型,自己打磨决定,一般情况下,4-6渲染帧左右为一逻辑帧比较合理,大概1S的时间内,客户端会收到服务器8-10个逻辑帧输入。

      后台实现

      1、核心思想

      对于后台开发来说,服务器主要起到控制作用,对客户端的帧信息进行输入输出管理,服务器就像是一个时间序列的驱动器,每隔一定间隔,会把在这段时间间隔收集到得客户端的输入,下发广播到所有客户端中去,从而驱动客户端执行帧同步处理,简而言之可以看作服务器在时间轴序列上,收集切片,每隔一定间隔,把这时间切片收集到的数据下发给客户端。

      1.对于帧同步来说,数据同步的频率较高,当然是希望越小的网络延迟越佳,由于TCP的滑动窗口和重传机制,导致延时无法控制,因此帧同步一般采用udp进行网络传输。提到udp这里就会衍生出可靠性的问题,对于客户端来说,如果某些udp包没有收到该怎么办呢,这就是帧同步客户端会出现的丢帧的情况,这时候得靠客户端与服务器指定针对性的重传机制.

      2.服务器单局中数据首先对每一帧下发客户端的数据进行编号,然后并保存下来,某某客户端网络不佳,中途丢了一些包,可以跟服务器发请求,我现在播放到哪一个序列号的帧了,服务器可以把这个客户端当前序号的帧和客户端缺省的帧一并下发,这样客户端拿到数据后,便可继续通过合帧快播的方式,加速播放,赶上当前时间。这样客户端的表现就是在快放一样。

      3.一般来说,帧同步的方案的包量都是比较小的,对于客户端在这个时间间隔没有上传任何数据,服务器也得帮该客户端构造空帧出来,免得其他客户端出现没有输入的情况出现。

      4.对于短时间的大量重传,服务器可以选择性的采取合并的策略,减少客户端的瞬间的收包数量。同时也可以利用好不超过mtu的包量大小,尽可能的携带一些之前若干个时间帧的信息,最大限度的把信息push到给客户端,减少客户端申请重传的概率.

      2、断线重连

      服务器单局可以把所有逻辑帧存储下来,当客户端断线,重新登陆的时候,服务器可以将所有的逻辑帧下发给客户端,客户端拿到所有的逻辑帧后,可以快速在后台跑完全部的逻辑帧,当跑完后,加载到画面,就重新回到游戏单局了。由于断线时,跑的是单局上所有客户端一样的逻辑帧,因此,等到恢复游戏的时候玩家的状态是一致的。

      3、反外挂

      服务器都是切逻辑帧,没有感知到客户端的逻辑,所以反外挂这块不方便校验,可以从以下两方面着手去校验 1.由于所有客户端的数据都是一致的,可以让客户端根据自身数据算出若干个特征值,严格来说, 所有的客户端算出来的特征值都应该是一样的,因为他们的数据是一样的,当有玩家不一致的时候,可以断定该玩家有作弊的嫌疑。 2.通过单局过程或者完成的时候,汇报统计信息给服务器,服务器通过若干个数据的关联关系,进行数据校验。(有点类似手游单机游戏的校验)

      4、特殊关注的点

      1.随机性:游戏中不可避免会有随机的逻辑,这时候伪随机就派上用场了,通过下发统一的随机种子,确保每个客户端都产生相同的随机序列。 war3中暴击就是使用的伪随机机制,同样是为了应付帧同步的问题而产生的解决方式。

      2.浮点数:浮点数尽可能的避免,还有特殊注意的是,如果用了第三方的库,要确保客户端在不同平台的计算结果是一致的,比方说用了某些物理引擎,在安卓和IOS的平台上会有可能计算出不同的结果,那就要在开发过程中,注意避免使用平台不一致的API了。

      3.调试难度

      帧同步调试比较困难,需要良好的Log系统,针对不一致的情况能通过Log追溯原因。

      尽早的搭建起录像功能通过录像回放可以反复观看逻辑上的不同步,方便问题定位。

      在单局中增加debug模式下不一致的检查,当发生不一致时,及时发现,定位原因。如果能引入自动化测试那效果就更佳了。

      2、位置同步

      原理

      位置同步比较好理解,并且最开始一批手游的Pvp也是大多采用位置状态同步的方法。位置同步跟帧同步的最大区别是服务器不在进行切逻辑帧,而是被动的帮助客户端转发位置状态同步包,从而实现同步的目的。比说存在玩家A、B、C,玩家A上报自己的位置和状态给服务器S,服务器S把这个玩家上报的包广播给玩家B、玩家C,玩家B、C收到包后,知道了玩家A的位置和状态,做相应的逻辑。由于存在网络延迟,位置同步的方式会导致接收方收到的包是发送方之前历史时间的包, 存在一定滞后性。需要获得较低的网络延迟,可以通过udp的方式去发送同步包,发送包的频率相对帧同步来说可以低一点,服务器上可以处理跟单局相关的逻辑(使用道具等),能感知到单局中的信息。

      后台实现

      1.核心思想

      位置同步的后台相对容易实现,只需要管理好单局的生命周期就好了,控制单局开始、单局结束,在单局过程中通过UDP传输玩家的位置状态同步包,重要的信息可以通过tcp传输给服务器作逻辑仲裁(使用道具,攻击他人等),客户端收到回包做对应的展示逻辑,只要客户端每秒上报给服务器的包数量足够多,那其他客户端在1s内可以拿到多个同步包,能对该客户端在本地的位置状态做出及时的修正,从而达到各个客户端同步的目的。

      2.反外挂

      位置同步反外挂是比起帧同步来说是更容易实现的,首先因为重要的数据是跟服务器有交互的,因此服务器单局数据中存储着玩家的数据信息,比如说玩家在当前时间在单局中拥有的道具,玩家在地图上的大概位置。打个比方,客户端经常出现使用自身都不存在的道具,经常发起cs请求给服务器,服务器本身是有玩家身上道具信息的,那可以判定玩家有一定的作弊嫌疑。另外一个例子,赛车游戏,上一个客户端上报的同步包还在赛道的中段位置,下一秒玩家上报自己冲线了,这些后台马上就感知到了,客户端存在作弊嫌疑。

      3.断线重连

      CS同步的断线重连,要看服务器对单局的参与深度,如果服务器上有大量的玩家当前状态位置信息,那玩家重连回来的时候可以通过服务器下发当前的所有玩家状态位置信息给掉线的玩家,掉线玩家拿到全量信息后,马上能重建单局情景,恢复游戏。如果服务器介入不深,其实这时候就只有客户端才有这个完整时间切片的全量位置状态信息了,服务器可以随机挑选一个网络状况较好的客户端,向该客户端发起拉取全量位置状态信息的请求,就好像是服务器向客户端拉取一个时间切片的请求一样,把该客户端在这个时间点上的所有信息汇总报上服务器,服务器拿到全量信息后,下发给掉线重连的客户端,这样掉线的客户端也能拿到全量的数据信息,并恢复单局。在开发过程中,得与前台协商后,要在开发前期就考虑到恢复机制的需求,客户端数据管理统一模块化。

      案例:天飞及新赛车手游PVP系统方案

      上文主要阐述理论方法论,下文结合实际项目谈谈方案的实施。 游戏类型很大程度上决定了同步方案的选择,赛车游戏需要瞬时的强交互的情景比较少,只有车与车碰撞相互挤压这瞬间才体现出这种情景的需求。因此从技术选型上一开始就倾向使用CS位置同步了,以前做天飞的PVP系统,由于是线上项目,一个版本的时间就一个月左右,不大可能推翻客户端架构采用帧同步的技术方案,因此天飞的之前的Pvp采用的是CS位置同步技术方案,后台开发思想遵循以下思路进行开发的,稳定—>可扩展—>性能,试想下pvp服务器是一个有状态的服务器,如果外网经常出现不稳定导致服务器无法服务,那将会是同一台机器的上万名玩家同时掉线,这在产品运营层面上是不可以接受的,因此稳定是所有要求的首位。其二现在手游浪潮变化快,一不小心服务器承载就爆满了,可能过一段时间新玩法一出来,一下子又涌到新系统上去了,当初部署的机器就面临空负载问题,因此在解决稳定可靠后,要提高系统的可伸缩性,最后剩下的问题就是性能了。

      一、自适应网络切换

      为了保证可靠性,针对手机的网络情况作了针对性的优化策略。众所周知,手机网络特点不稳定,尤其是在网络切换过程中,会出现闪断。在wifi环境下延迟大概保证在40-80ms之间,如果是3G网络的话,外网真实的延迟平均在60-200ms之间波动,非常不稳定(取自天飞外网PVP统计数据)。pvp中对于位置状态的同步信息,客户端优先考虑p2p直接发送,通过udp进行发送,对于其他重要的请求,通过tcp与客户端通信,位置同步包。对此,服务器后台跟客户端的通信采用了自适应的网络切换,既能满足对效率的要求,又能保证网络的可靠性。 单局开始前,服务器会跟所有的客户端打通udp通道,并且在开局时把Ip端口都广播给所有客户端,客户端自行进行p2p通信同步位置。当客户端感知到P2p无法通信时,会将网络包通过UDP发送到服务器上,服务器通过UDP进行同步包的转发,当服务器感知到与某玩家udp网络不畅通时,服务器会自动切换到tcp上跟客户端进行同步包的通信。简而言之,最开始客户端相互p2p传递,发现网络不佳,使用服务器udp进行转发,服务器感知到与某一客户端网络不佳,针对该玩家的后续同步包会切换成TCP进行转发。 而这一切的网络切换完全是在网络底层进行触发的,应用层无法感知到。实现的原理类似TCP的ACK确认机制,将以图文结合的形式描述。

    <ignore_js_op>
     

      *在网络消息的头部带上两个时间戳,起到关键性作用的两个字段为:

      m_u32UdpServerTime; //服务器最后给客户端发送udp包时间 (服务器使用该字段判断与客户端是否收到UDP包)

      m_u32ClientUdpTime;        //客户端最后给服务器发送udp包时间 (客户端根据该字段判断与服务器是否收到UDP包)

      下面以服务器为例,描述如何感知到客户端与服务器的udp网络不佳的,转而切换通过TCP网络发送消息。

      服务器维护两个变量

      WaitConfirmTime(待确认收到服务器时间戳)

      ConfirmTime(已经确认收到服务器时间戳)

      最开始服务器像客户端发UDP同步包,此时时刻为t1,可以理解成这个包的Seq为t1,此时服务器变量WaitConfirmTime就变为t1,说明服务器在t1时间发过包给客户端,不知道客户端收到没收到,要等待确认。

      当客户端收到刚才的udp包,客户端会在他下一个要发给服务器的任意TCP或者UDP包中回带时间戳回来(图中红色回带Seq:t1),目的是为了让服务器知道刚才t1时间的包,客户端已经确认收到了,当服务器收到这个包时,知道客户端已经收到包了,服务器的变量ConfirmTime就更新为t1.,此时WaitConfirmTime和ConfirmTime是相等的,那么可以认为网络是不错的,因为服务器发出的包,客户端全部都被确认收到了。

      实际情况是WaitConfirmTime一直都会比ConfirmTime是要超前的,两者交替增大,因为收到客户端确认肯定没有发出的时间快,判断网络是否尚且良好的标准是,当我要发给该客户端发包的时候,我会先看下该客户端的ConfirmTime、WatiConfirmTime和当前的时间戳三者关系,首先如果WaitConfirmTime大于ConfirmTime(说明还有包客户端没收到,所以没确认)超过一定阈值的时候,则认为服务器一直发的包客户端都没有收到,此时服务器会自动切换成TCP给客户端转发同步位置包,确保客户端能收到。 

    <ignore_js_op>

    <ignore_js_op>

      客户端判断与其他客户端p2p网络状况切换,判断与服务器udp的网络状况都是跟上述服务器是同一个道理,只不过使用的是包头的不同的字段而已。

      真实外网数据情况:平均单局时长3分钟,一个玩家每秒的同步包频率3-7个,自适应网络切换的阈值为5S,UDP打通率大概在73.2%左右, Wifi玩家占比三分之二左右,在外网完全利用p2p完成单局人数只有7%左右, 完全使用p2p和udp包完成单局的人数为63.2%,掉线率大概在5%上下

      通过外网的数据得出一些结论,手机网络的情况还是不太适合使用p2p的方式进行通信,后续新手游的网络开发也没有使用P2P的方式了,而是直接一开始就通过服务器用udp方式进行同步位置转发。手游网络不稳定,闪断会比较多,因此非常有必要做单局内的断线重连。

      二、断线重连

      断线重连由于服务器没有介入很深,因此当玩家掉线的时候,玩家资源并没有及时进行销毁,而是保留到单局结束的时候再进行统一销毁。(衍生出特殊情况,玩家都掉线了,单局里面没人,因此无法驱动下去,导致资源无法回收,得增加checkinvalid的操作,需要检查长时间没有网络交互的单局,超时便可强行回收资源)。断线重连采取的是向其中一个客户端拿取时间切片的方式恢复单局信息。

      三、扩展伸缩性

      稳定的问题得到解决,在扩展伸缩性上,由于天飞算是第一批上PVP系统的手游,当时市面上没有太多的参考,因此在上线前作出了充分的压测,并在运维、运营管理方面充分考虑,预埋了多处开关,从而应对营运峰值状况的发生。

      1.PVP服务器支持不停机更新,动态添加减少机器服务。

      玩家是通过匹配服务器决定登陆到哪台Pvp服务器上进行多人游戏,匹配服务器上相当于是一个center,知道当前所有pvp服务器上的玩家承载,当需要重启某台Pvp服务器的时候,可以通过在这台pvp服务器上刷配置,配置生效后,反向通知center匹配服务器,使得后续玩家不会分配到该pvp服务器上,等到该pvp服务器上的单局都结束了(持续3分钟左右),便可以随意操作该服务器,可以替换程序,可以动态下架等。 这样做的好处是,刚上线的时候遇到外挂问题比较严重,在问题暴露后,马上修改代码添加了针对性的策略,直接不停机在用户毫无感知的情况下,在白天就把全部外网的Pvp服务器重启更新了。

      2.影响性能的关键项配置化

      a.客户端相关的(每秒同步包的基础数量配置化)

      在跟客户端同事协商,在不同情况下每秒发送的同步包数量也是动态变化的,不用使用固定的同步频率,以赛车游戏为例,当我没有任何操作,行驶在直道上时,可以相对应的降低同步频率,当我快速变向或者过弯等情况,可以动态增加同步的包量,总而言之,根据自己游戏场景,动态调节同步频率,从而达到节省同步包量,降低服务器负载。

      b.服务器内部的

      当时压测发现,服务器主要的瓶颈在于CPU,单进程的服务,人数越多,每秒处理的包量就越大,pvp上的逻辑都不太重,主要的cpu消耗都在打解网络包上,当时天飞使用的是最原始的tconnd,加解密也是server自己做的,加密和解密势必会消耗更多的cpu资源。当时留了开关,针对下行包的位置状态信息,设置了不加密的开关。这个数据即便不加密影响也是最小的。为的就是留有更大的运营余地,在面对运营峰值的时候,所采用的权宜之策。

      四、反外挂

      从两方面,一方面是处理重要游戏过程都是通过tcp与客户端交互的,服务器为进行校验。另一方面单局过程中,客户端每隔一定时间,会上报该时间段内的统计信息,单局结束后,会上报全局的统计信息,服务器收集到这些统计数据后,会进行后校验。

      总结

      本文主要阐述了帧同步和CS位置同步的原理和主要实现方法,并针对实际项目,整理了自身在做pvp系统所累积到的一些经验心得,由于个人力量有限,难免有纰漏之处。pvp同步的流畅体验,一方面靠的是技术方案的设计,另一方面还离不开策划程序在某些数值上的精细打磨,在数值打磨的方法论上,没有放之四海而皆准的准则,唯一的方法是根据已有经验不断尝试(比如说,同步包频率的设计,客户端提前预测的算法等等),无论使用的是帧同步方案还是CS位置同步方案,相信也会有许多这样需要跟游戏特性相关的参数需要后期打磨设定,才能获得流畅的多人同步体验。不同的游戏类型、不同的团队技术积累,可能就会选择不同的技术方案。无论是何种技术方案,流畅的pvp体验单靠后台给力实现是远远不够的,归根到底还是后台前台策划团队合力的结果。

    转载于:https://www.cnblogs.com/xiaoleiel/p/8334139.html

    展开全文
  • 深入理解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...

    UDP协议

    UDP(User Datagram Protocol),用户数据报协议,是OSI(Open System Interconnection,开放式系统互联) 参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,IETF RFC 768是UDP的正式规范。UDP提供了无连接通信,且不对传送数据包进行可靠性保证,适合于一次传输少量数据,UDP传输的可靠性由应用层负责。

    UDP报文没有可靠性保证、顺序保证和流量控制字段等,可靠性较差。但是正因为UDP协议的控制选项较少,在数据传输过程中延迟小、数据传输效率高,适合对可靠性要求不高的应用程序,或者可以保障可靠性的应用程序,如DNS、TFTP、SNMP等。
    UDP在IP报文中的位置如下图所示:
    这里写图片描述
    可以看到,UDP其实就是在IP报文中添加了端口信息,使数据到达主机后送达至相应端口的应用程序。下面是通过wireshark抓的一个UDP数据包:
    在这里插入图片描述


    UDP使用

    在选择使用协议的时候,选择UDP必须要谨慎。在网络质量令人十分不满意的环境下,UDP协议数据包丢失会比较严重。但是由于UDP的特性:它不属于连接型协议,因而具有资源消耗小,处理速度快的优点,所以通常音频、视频和普通数据在传送时使用UDP较多,因为它们即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。比如我们聊天用的QQ就是使用的UDP协议。

    既然UDP是一种不可靠的网络协议,那么还有什么使用价值或必要呢?其实不然,在有些情况下UDP协议可能会变得非常有用。因为UDP具有TCP所望尘莫及的速度优势。虽然TCP协议中植入了各种安全保障功能,但是在实际执行的过程中会占用大量的系统开销,无疑使速度受到严重的影响。反观UDP由于排除了信息可靠传递机制,将安全和排序等功能移交给上层应用来完成,极大降低了执行时间,使速度得到了保证。


    UDP报头

    UDP报头由4个域组成,其中每个域各占用2个字节,如下图所示:
    这里写图片描述

    • UDP协议使用端口号为不同的应用保留其各自的数据传输通道。UDP和TCP协议正是采用这一机制实现对同一时刻内多项应用同时发送和接收数据的支持。数据发送一方(可以是客户端或服务器端)将UDP数据包通过源端口发送出去,而数据接收一方则通过目标端口接收数据。有的网络应用只能使用预先为其预留或注册的静态端口;而另外一些网络应用则可以使用未被注册的动态端口。*因为UDP报头使用两个字节存放端口号,所以端口号的有效范围是从0到65535。*一般来说,大于49151的端口号都代表动态端口。

    • 数据报的长度是指包括报头和数据部分在内的总字节数。因为报头的长度是固定的,所以该域主要被用来计算可变长度的数据部分(又称为数据负载)。数据报的最大长度根据操作环境的不同而各异。从理论上说,包含报头在内的数据报的最大长度为65535字节。不过,一些实际应用往往会限制数据报的大小,有时会降低到8192字节。(对于一次发送多少字节比较好,后面会讲到)

    • UDP协议使用报头中的校验值来保证数据的安全。校验值首先在数据发送方通过特殊的算法计算得出,在传递到接收方之后,还需要再重新计算。如果某个数据报在传输过程中被第三方篡改或者由于线路噪音等原因受到损坏,发送和接收方的校验计算值将不会相符,由此UDP协议可以检测是否出错。这与TCP协议是不同的,后者要求必须具有校验值。

    • 许多链路层协议都提供错误检查,包括流行的以太网协议,也许你想知道为什么UDP也要提供检查和校验。其原因是链路层以下的协议在源端和终端之间的某些通道可能不提供错误检测。虽然UDP提供有错误检测,但检测到错误时,UDP不做错误校正,只是简单地把损坏的消息段扔掉,或者给应用程序提供警告信息。


    UDP特性

    UDP是一个无连接协议,传输数据之前源端和终端不建立连接,当UDP它想传送时就简单地去抓取来自应用程序的数据,并尽可能快地把它扔到网络上。在发送端,UDP传送数据的速度仅仅是受应用程序生成数据的速度、计算机的能力和传输带宽的限制;在接收端,UDP把每个消息段放在队列中,应用程序每次从队列中读一个消息段。

    由于传输数据不建立连接,因此也就不需要维护连接状态,包括收发状态等,因此一台服务机可同时向多个客户机传输相同的消息。

    UDP信息包的标题很短,只有8个字节,相对于TCP的20个字节信息包的额外开销很小。

    吞吐量不受拥挤控制算法的调节,只受应用软件生成数据的速率、传输带宽、源端和终端主机性能的限制。

    UDP使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的链接状态表(这里面有许多参数)。

    UDP是面向报文的。发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付给IP层。既不拆分,也不合并,而是保留这些报文的边界,因此,应用程序需要选择合适的报文大小。


    对UDP一次发送多少bytes好?问题的思考

    在进行UDP编程的时候,我们最容易想到的问题就是,一次发送多少bytes好? 当然,这个没有唯一答案。相对于不同的系统,不同的要求,其得到的答案是不一样的。我这里仅对像ICQ一类的发送聊天消息的情况作分析,对于其他情况,或许也能得到一点帮助。

    首先,我们知道TCP/IP通常被认为是一个四层协议系统,包括链路层、网络层、传输层、应用层。UDP属于传输层,下面我们由下至上一步一步来看: 以太网(Ethernet)数据帧的长度必须在46-1500字节之间,这是由以太网的物理特性决定的。 这个1500字节被称为链路层的MTU(最大传输单元)。 但这并不是指链路层的长度被限制在1500字节,其实这个MTU指的是链路层的数据区并不包括链路层的首部和尾部的18个字节。所以事实上这个1500字节就是网络层IP数据报的长度限制。因为IP数据报的首部为20字节,所以IP数据报的数据区长度最大为1480字节。而这个1480字节就是用来放TCP传来的TCP报文段或UDP传来的UDP数据报的。又因为UDP数据报的首部8字节,所以UDP数据报的数据区最大长度为1472字节。这个1472字节就是我们可以使用的字节数。

    当我们发送的UDP数据大于1472的时候会怎样呢? 这也就是说IP数据报大于1500字节,大于MTU。这个时候发送方IP层就需要分片(fragmentation)。把数据报分成若干片,使每一片都小于MTU。而接收方IP层则需要进行数据报的重组。这样就会多做许多事情,而更严重的是,由于UDP的特性,当某一片数据传送中丢失时,无法重组数据报,将导致丢弃整个UDP数据报。因此,在普通的局域网环境下,建议将UDP的数据控制在1472字节以下为好。

    进行Internet编程时则不同,因为Internet上的路由器可能会将MTU设为不同的值. 如果我们假定MTU为1500来发送数据的,而途经的某个网络的MTU值小于1500字节,那么系统将会使用一系列的机制来调整MTU值,使数据报能够顺利到达目的地,这样就会做许多不必要的操作. 鉴于Internet上的标准MTU值为576字节,所以我建议在进行Internet的UDP编程时. 最好将UDP的数据长度控件在548字节(576-8-20)以内.


    UDP协议:低开销通信

    UDP是一种简单协议,提供了基本的传输层功能。与TCP相比,UDP的开销极低,因为UDP是无连接的,并且不提供复杂的重新传输、排序和流量控制机制。

    UDP数据报重组

    与TCP的通信机制不同,由于UDP是无连接协议,因此通信发生之前不会建立会话。UDP是基于事务的,换言之,应用程序要发送数据时,它仅是发送数据而已。很多使用UDP的应用程序发送的数据量很小,用一个数据段就够了。但是也有一些应用程序需要发送大量数据,因此需要用多个数据段。UDP PDU(协议数据单元)的实际意义是数据报,尽管数据段和数据报可以互换使用来描述某个传输层PDU。

    	将多个数据报发送到目的主机时,它们可能使用了不同的路径,到达顺序也可能跟发送时的顺序不同。与TCP不同,UDP不跟踪序列号。UDP不会对数据报重组,因此也不会将数据恢复到传输时的顺序。
    	因此,UDP仅仅是将接收到的数据按照先来后到的顺序转发到应用程序。如果数据的顺序对应用程序很重要,那么应用程序只能自己标志数据的正确顺序,并决定如何处理这些数据。
    

    UDP服务器进程与请求

    与基于TCP的应用程序相同的是,基于UDP的服务器应用程序也被分配了公认端口或已注册的端口。当上述应用程序或进程运行时,它们就会接受与所分配端口相匹配的数据。当UDP收到用于某个端口的数据报时,它就会按照应用程序的端口号将数据发送到相应的应用程序。

    UDP客户端进程

    对于TCP而言,客户端/服务器模式的通信初始化采用由客户端应用程序向服务器进程请求数据的形式。而UDP客户端进程则是从动态可用端口中随机挑选一个端口号,用来作为会话的源端口。而目的端口通常都是分配到服务器进程的公认端口或已注册的端口。

    采用随机的源端口号的另一个优点是提高安全性。如果目的端口的选择方式容易预测,那么网络入侵者很容易就可以通过尝试最可能开放的端口号访问客户端。

    由于UDP不建立会话,因此一旦数据和端口号准备就绪,UDP就可以生成数据报并递交给网络层,并在网络上寻址和发送。

    需要谨记的是,客户端选定了源端口和目的端口后,通信事务中的所有数据报文头都采用相同的端口对。对于从服务器到达客户端的数据来说,数据报头所含的源端口和目的端口作了互换。

    展开全文
  • 终于懂了TCP和UDP协议区别

    万次阅读 多人点赞 2020-03-26 12:03:28
    终于懂了TCP和UDP协议区别
  • UDP

    千次阅读 2018-08-13 22:54:34
     用户数据保协议(User Datagram Protocol,UDP)是开放系统互联模型(Open System Interconnection,OSI)中传输层协议的一种,是一种保留消息边界的简单的面向数据报的协议。UDP不提供差错纠正、队列管理、重复...
  • 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连接传送的数据,无差错,不丢失,不重复,且按序到达;...
  • TCP和UDP的最完整的区别

    万次阅读 多人点赞 2016-08-04 11:30:30
    TCP和UDP两种协议的比较汇总
  • 网络协议 -- UDP协议(1)介绍

    万次阅读 多人点赞 2017-12-28 16:12:59
    一、什么是UDP协议? UDP是User Datagram Protocol的简称,中文名是用户数据报协议,是OSI参考模型中的传输层协议,它是一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。 UDP的正式规范是IETF RFC...
  • TCP与UDP区别详解

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

    万次阅读 多人点赞 2018-12-26 17:16:34
    UDP数据报 一、UDP的概述 二、UDP的首部格式 UDP校验
  • Netty之UDP协议开发

    万次阅读 热门讨论 2016-11-21 20:49:22
    UDP协议简介UDP是用户数据报协议(User Datagrame Protocol,UDP)的简称,主要作用是将网络数据流压缩成数据报的形式,提供面向事务的简单信息传送服务。
  • 【LwIP - UDP】 - udp_bind和udp_connect分析

    千次阅读 2018-09-07 16:53:27
    udp_bind和udp_connect两者具体的工作原理,笔者在网上找不到正确的说法。对此,笔者主要对UDP中的这两个接口进行分析。 1 udp_bind udp_bind将一个UDP PCB与IP和端口进行绑定。当然不是简简单单的把该IP和端口...
  • 终于把TCP协议与UDP协议给整明白了

    万次阅读 多人点赞 2020-07-04 21:35:16
    网络编程有三个要素,分别是IP地址、端口号和通信协议,本文主要讲述的是TCP与UDP这两种通信协议,以及编程的实现。
  • UDP协议详解

    千次阅读 2018-10-24 19:19:00
    一、UDP概述   UDP 是 User Datagram Protocol 的简称, 中文名是用户数据报协议,是一个简单的面向数据报的传输层协议,在网络中用于处理数据包,是一种无连接的协议。UDP 不提供可靠性的传输,它只是把应用程序...
  • 关于IOCP网络模型的介绍可以...IOCP模型对协议是没限制的,无论是TCP还是UDP都是支持的。 UDP的IOCP模型实现的不同之处在于投递发送请求和接受请求所用的函数不同: int WSARecvFrom( SOCKET s, LPWSABUF lpBuffe
  • Netty UDP Client & Server

    万次阅读 热门讨论 2018-01-31 17:47:48
    netty 客户端和服务器UDP通信 NettyUdpServer package com.vrv.cems.service.logpush.core; import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; import io.netty.channel....
  • UDP理论详解

    万次阅读 2016-06-28 21:54:40
    最开始的连接层协议种类繁多(Ethernet、Wifi、ARP等等)。到了网络层,我们只剩下一个IP协议(IPv4和IPv6是替代关系)。进入到传输层(transport layer),协议的种类又开始繁多起来(比如TCP、UDP、SCTP等)。这就好像...
  • 一、用户数据报协议(UDP)简介 UDP是一种保留消息边界的简单的面向数据报的传输层协议 UDP特性 它不提供差错纠正、队列管理、重复消除、流量控制和拥塞控制 不提供差错纠正:它把应用程序传给IP层的数据发送...
  • UDP to UDP 数据转发

    千次阅读 2008-04-06 09:16:00
    目的 希望读者在阅读本文之前,已经读过了《『黑客编程』一、TCP to TCP 数据转发》,UDP to UDP可以用作QQ通过转发代理聊天的功能。应用机器A,提供UDP端口的服务,转发代理机器B,提供UDP转发端口服务,客户机C...
  • Linux 网络编程——UDP编程

    万次阅读 2015-04-16 20:26:34
    概述UDP 是 User Datagram Protocol 的简称, 中文名是用户数据报协议,是一个简单的面向数据报的运输层协议,在网络中用于处理数据包,是一种无连接的协议。UDP 不提供可靠性的传输,它只是把应用程序传给 IP 层的...
  • LwIP之UDP协议实现

    千次阅读 2017-10-13 14:22:30
    UDP理论UDP控制块 每一个UDP连接都对应一个UDP控制块,UDP协议的实现就是对这些控制块结构成员进行操作。为什么需要控制块链表?为了让协议栈可以实现多个连接,可以多个网络进程同时进行。最后这些控制块通过链表...
  • UDP通信

    千次阅读 2019-05-29 16:14:59
    UDP通信UDP简介UDP协议特性UDP协议与TCP协议的主要区别TCP协议简介TCP协议特性主要区别UDP协议应用场景UDP通信代码Linux系统下的UDP通信代码发送端接收端(阻塞模式)接收端(非阻塞模式)Windows系统下的UDP通信...
  • LWIP UDP 编程

    2018-04-13 09:08:52
    一、udp.c实现的函数 1、void&nbsp;udp_input(struct pbuf *p, struct netif *inp) 说明:处理接收到的udp数据包。 参数:p数据包缓存区;inp网络接口。 &nbsp;&nbsp;&nbsp; 2、err_t&...
  • 声明:本文来自腾讯增值产品部官方公众号小时光茶社,为CSDN原创投稿,未经许可,禁止任何形式的转载。 作者:黄日成,手Q游戏中心后台开发,腾讯高级工程师。从事C++服务后台开发4年多,主要负责手Q游戏中心后台...
  • Udp的反向代理:nginx

    千次阅读 2018-04-19 11:05:44
    在实时性要求较高的特殊场景下,简单的UDP协议仍然是我们的主要手段。UDP协议没有重传机制,还适用于同时向多台主机广播,因此在诸如多人会议、实时竞技游戏、DNS查询等场景里很适用,视频、音频每一帧可以允许丢失...
  • 很早就计划写篇关于UDP的文章,尽管UDP协议远没TCP协议那么庞大、复杂,但是,要想将UDP描述清楚,用好UDP却要比TCP难不少,于是文章从下笔写,到最终写成,断断续续拖了好几个月。 说起网络socket,大家自然会想到...

空空如也

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

udp中途切换wifi