闲聊:最近想要做一个用在网络游戏领域的网络控制协议小玩具,大体聊聊构思的想法

本文主要是介绍闲聊:最近想要做一个用在网络游戏领域的网络控制协议小玩具,大体聊聊构思的想法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这个控制协议跟 “猛禽 UDP/IP Aggligator 宽频聚合器”,是不同的,因为预期该网络控制协议,预计侧重在网络游戏加速这块。

所以它与多数网络控制协议,会有一定的不同。

但要先分析具体的目标场景,基本现代所有的 UDP/IP 应用层网络协议,都具备丢包重传控制,当然有一些是不在乎丢包的。

所以,一般来说保证 UDP/IP 不丢包,是没有太大意义的,因为这只会出现以下两种情况:

1、UDP/IP 网络应用,可以丢包,它们会忽略这类问题,因为不重要。

2、UDP/IP 网络应用,自己带了,可靠CC(类似 KCP/TCP/QUIC 的控制协议)。

那么类似网络应用产品(有):

1、灵境奇谈 (封灵笔记)

2、CS:GO    (反恐精英:全球攻势/cs2)

3、Warframe(星际战甲)

回到正题,既然知晓了问题的所在,那么就来开始按照不同的应用场景来调优,每个不同的网络应用调优方法是不同的。

但,我们通常预期目标都是为了减少网络抖动、只要产生丢包,那么网络抖动就会非常严重,而且在现代网络之中,因为路由跃点之间的不同,客户端到服务器之间的网络路由是随时波动的,即便路由没有变动,也会因为路由本身的QOS管理策略,导致帧的先后顺序发生改变(即乱序问题)产生抖动问题,因为若客户端需要排序,那么在收到来自未来帧时,是先缓存在接收方队列之中,等待确认帧(包)的到达,在这个空窗期就会产生抖动问题。

所以对于游戏加速,为了质量最好,会有两个以下解决方案:

1、对于UDP/IP带控制协议的网络游戏

我们可以采用,当收到游戏UDP数据包之后立即发出到服务器,并且为每个数据包标记帧序号,接收方,可以根据在1 ~ 5个毫秒内跳过的帧号,来评估网络的丢包层度。

注意:是采用旁路观察的办法,即控制协议来决定,发送方应该发送多少个冗余包,即:当收到客户端A包之后,发出几个包到服务器,如果丢失了一个包、由于冗余多发,虽然占用了更大的带宽,但延迟、抖动这块是基本被抹平了。

比如:

我们可以通过测算出来的每个帧需要发送几次,可以评估为:10个包丢一个包,则冗余发送一个包,5个包丢一个包,则冗余发送两个包,虽然这可能浪费更多的网络带宽。

网络之中5个包丢一个包,放大到3倍,产生一个包都无法到达的可能性几乎是没有的,在保证RTT、抖动不变大的情况,这是最佳解决方案,即通过冗余传送来保证。

但接收方一般拿需要确保不会出现重复帧转发的问题,即可:接收方收到已经转发过的帧不能再次转发,但为了可靠性也可以再次转发过去,让目的服务器自己处理它,但前提是目的是服务器允许这样的行为,这个要靠人们自己去测算。

网络游戏加速一般都是定向分析,定向研究加速解决方案的。

另外一种是做一个带ARQ(自动请求重传)的控制协议,这种像TCP/IP流控协议的做法就没有那么好了。

我们可以如此这般设计并处理,但它仍旧会产生一个抖动问题。

1、帧带上序号跟确认号。

2、接收方收到帧后,如果是当前确认号就确认并且交付

     如果序号小于确认号,只要不是序号回绕问题,就丢弃帧。

     如果序号大于确认号,就预先缓存在接收方队列之中。

     当然如果缓存的数据包,已经占用了窗口大小的 50% 以上,就立即发出ACK+NAK包

     另外为了提高效率,当连续收到 “2 ~ 3” 个来自未来的包(跳过),那么可以立即发出ACK+NAK 包,但建议是放在跟下面 Delay 一毫秒后在处理。(可以理解为:快速重传机制)

     否则检查设定一个毫秒后ACK的计时器句柄,在一个毫秒之后检查,因为这一个毫秒过后可能网卡会达到无数个包,此时在判断那些包已经收到,那些包被跳过,在发出ACK+NAK数据包告诉服务器,可以一定减少昂贵的带宽资源浪费。

       

     接收方收到ACK+NAK包以后,更新发送方的窗口大小,并且删除自己的已经缓存的数据包(尽快释放内存资源占用)、并且NAK上面指示的没有收到包重新发送出去。

    注意:NAK为否定应答(即接收方发出没有收到的帧到发送方),对的网络游戏加速,比较适合按照帧来确认,帧填充的方式来传输,而不是流式传输。

   重传时间(测算):默认情况下单位为1秒,在第一个测量出来的RTT(往返时间)这个可以从链接握手时确定。

   即:客户端发送链接建立的帧、到服务器应答客户端应答帧的第一个RTT时间作为SRTT、RTT_VAL(RTT/2)初始值。

关于重传时间的时间可以采用下面的公式,TCP/IP(但需要魔改)

R = RTT

SRTT = 平滑RTT时间

RTTVAL = RTT因子

第一个RTT测量:

K = 4(常数)

SRTT = R

RTTVAR = R/2

RTO = SRTT + max(G,K*RTTVAR)

第二个RTT测量:(及之后)

注意:它需要通过 “NPU/SSE” 浮点数来运算

alpha=1/8

beta=1/4

RTTVAR = (1 - beta) * RTTVAR + beta * |SRTT - R|            

SRTT = (1 - alpha) * SRTT + alpha * R

RTO = SRTT + max (G, K*RTTVAR)

补充:

G为时间精度常数,在内核之中它被设定为200毫秒。

Linux TCP_RTO_MIN, TCP_RTO_MAX and the tcp_retries2 sysctl (pracucci.com)

#define TCP_RTO_MAX ((unsigned)(120*HZ))
#define TCP_RTO_MIN ((unsigned)(HZ/5))

下述为KCP控制协议算法的RTO重传时间计算公式:

      它与上面的公式区别不大,只是对系数微调的区别,即:KCP约为TCP/IP控制协议重传时间除以1.25~1.5倍左右。

static void ikcp_update_ack(ikcpcb *kcp, IINT32 rtt)
{IINT32 rto = 0;if (kcp->rx_srtt == 0) {kcp->rx_srtt = rtt;kcp->rx_rttval = rtt / 2;}	else {long delta = rtt - kcp->rx_srtt;if (delta < 0) delta = -delta;kcp->rx_rttval = (3 * kcp->rx_rttval + delta) / 4;kcp->rx_srtt = (7 * kcp->rx_srtt + rtt) / 8;if (kcp->rx_srtt < 1) kcp->rx_srtt = 1;}rto = kcp->rx_srtt + _imax_(kcp->interval, 4 * kcp->rx_rttval);kcp->rx_rto = _ibound_(kcp->rx_minrto, rto, IKCP_RTO_MAX);
}

     但同时,需要设置一个最小RTO时间的边界值(临界值),这个值根据实际生产需要,可以设置为40、100毫秒即可,但对于游戏加速这种场景设置为40 ~ 60毫秒,一般会比较合理,RTO不能太小,否则会浪费大量带宽的,我们应该通过快速重传的方式来处理,而不是依赖于设计的控制协议RTO自动重发来处理。

       

关于发送方,因为根据接收方传递过来的窗口大小来发送数据,为了提高效率:应该是对面接收方有足够接受能力收到足够大的字节数时,一次性把发送队列之中带传输的数据包输出过去,在根据接收方投递的ACK/NAK来实时更新窗口大小,以便评估是否需要继续发送数据到接收方。

但需要注意一点:接收方跟发送方之间,建议采用 “背负式确认” 的方式来处理,这可以减少没必要单独的 ACK 报文发出,节约两端的网络带宽资源,但这可能会带来一定对于网络控制协议栈编程的复杂度。

RTO 值得计算用KCP修改后的系数会比较好一些,当然人们仍旧可以大胆得重新调整系数,无外乎是牺牲更多带宽,还是更小网络带宽得问题,另外也可以选用 BBRplus(BBR+)得调效模式,尽量避免提高RTO重传时间,以避免网络吞吐效率的降低,但这会增加网络拥塞层度的问题。

补充:

简单说一说SWS问题(糊涂窗口综合症问题)

在控制协议之中,我们大家都是通过窗口来评估对方的接收能力,如果对方窗口堆满,我们就不能发送。

所以对方只要收取且交付数据就需要更新窗口大小,但不可能为了更新窗口大小,每次都去立即发出ACK报文。

我在上篇文中没有着重的探讨这个问题,而是说推迟确认(延迟1毫秒)都是为了解决,类似如这个SWS糊涂窗口问题。

但仍可以通过算法评估解决该问题的ACK发出时机。

可以窗口边缘滑动了:
1/4缓冲区 or 4个MSS大小

来评估是否立即发出ACK报文,迫使发送方更新接收方窗口大小,否则应在下个正常发出帧数据背负式确认。

这篇关于闲聊:最近想要做一个用在网络游戏领域的网络控制协议小玩具,大体聊聊构思的想法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/935618

相关文章

poj1330(LCA最近公共祖先)

题意:求最近公共祖先 思路:之前学习了树链剖分,然后我就用树链剖分的一小部分知识就可以解这个题目了,记录每个结点的fa和depth。然后查找时,每次将depth大的结点往上走直到x = y。 代码如下: #include<iostream>#include<algorithm>#include<stdio.h>#include<math.h>#include<cstring>

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

ASIO网络调试助手之一:简介

多年前,写过几篇《Boost.Asio C++网络编程》的学习文章,一直没机会实践。最近项目中用到了Asio,于是抽空写了个网络调试助手。 开发环境: Win10 Qt5.12.6 + Asio(standalone) + spdlog 支持协议: UDP + TCP Client + TCP Server 独立的Asio(http://www.think-async.com)只包含了头文件,不依

poj 3181 网络流,建图。

题意: 农夫约翰为他的牛准备了F种食物和D种饮料。 每头牛都有各自喜欢的食物和饮料,而每种食物和饮料都只能分配给一头牛。 问最多能有多少头牛可以同时得到喜欢的食物和饮料。 解析: 由于要同时得到喜欢的食物和饮料,所以网络流建图的时候要把牛拆点了。 如下建图: s -> 食物 -> 牛1 -> 牛2 -> 饮料 -> t 所以分配一下点: s  =  0, 牛1= 1~

poj 3068 有流量限制的最小费用网络流

题意: m条有向边连接了n个仓库,每条边都有一定费用。 将两种危险品从0运到n-1,除了起点和终点外,危险品不能放在一起,也不能走相同的路径。 求最小的费用是多少。 解析: 抽象出一个源点s一个汇点t,源点与0相连,费用为0,容量为2。 汇点与n - 1相连,费用为0,容量为2。 每条边之间也相连,费用为每条边的费用,容量为1。 建图完毕之后,求一条流量为2的最小费用流就行了

poj 2112 网络流+二分

题意: k台挤奶机,c头牛,每台挤奶机可以挤m头牛。 现在给出每只牛到挤奶机的距离矩阵,求最小化牛的最大路程。 解析: 最大值最小化,最小值最大化,用二分来做。 先求出两点之间的最短距离。 然后二分匹配牛到挤奶机的最大路程,匹配中的判断是在这个最大路程下,是否牛的数量达到c只。 如何求牛的数量呢,用网络流来做。 从源点到牛引一条容量为1的边,然后挤奶机到汇点引一条容量为m的边

配置InfiniBand (IB) 和 RDMA over Converged Ethernet (RoCE) 网络

配置InfiniBand (IB) 和 RDMA over Converged Ethernet (RoCE) 网络 服务器端配置 在服务器端,你需要确保安装了必要的驱动程序和软件包,并且正确配置了网络接口。 安装 OFED 首先,安装 Open Fabrics Enterprise Distribution (OFED),它包含了 InfiniBand 所需的驱动程序和库。 sudo

【机器学习】高斯网络的基本概念和应用领域

引言 高斯网络(Gaussian Network)通常指的是一个概率图模型,其中所有的随机变量(或节点)都遵循高斯分布 文章目录 引言一、高斯网络(Gaussian Network)1.1 高斯过程(Gaussian Process)1.2 高斯混合模型(Gaussian Mixture Model)1.3 应用1.4 总结 二、高斯网络的应用2.1 机器学习2.2 统计学2.3

PostgreSQL核心功能特性与使用领域及场景分析

PostgreSQL有什么优点? 开源和免费 PostgreSQL是一个开源的数据库管理系统,可以免费使用和修改。这降低了企业的成本,并为开发者提供了一个活跃的社区和丰富的资源。 高度兼容 PostgreSQL支持多种操作系统(如Linux、Windows、macOS等)和编程语言(如C、C++、Java、Python、Ruby等),并提供了多种接口(如JDBC、ODBC、ADO.NET等

网络学习-eNSP配置NAT

NAT实现内网和外网互通 #给路由器接口设置IP地址模拟实验环境<Huawei>system-viewEnter system view, return user view with Ctrl+Z.[Huawei]undo info-center enableInfo: Information center is disabled.[Huawei]interface gigabit