比如说,玩家去攻击一个怪物,我们把它放大为2个消息,[走到怪物跟前] [攻击怪物]。如果采用TCP协议,那么消息是连续的,先做第一个动作[走到怪物跟前],再做第二个动作[攻击怪物]。如果是UDP协议,那么这个消息可能发生倒序,可能变成了先[攻击怪物],然后[走到怪物跟前],这样看来就有点怪怪的。这个问题如何解决呢,其实在处理包的时候有一个逻辑层,这个问题本来是一个网络传输层的错误,但是我们可以将它转化为一个逻辑层的错误,我们可以认为凡是在怪物一定范围之外的近身攻击都是无效的(我想大多数网游服务器段都是这样处理的,没有哪个网游的战士能拿武器老远打怪的),无效的消息如何处理?很简单,丢掉,呵呵。 可能很多人不同意我最后的处理办法,没有关系,我说过了,这只是一部分特定的网游可以这么做,另外一方面,大部分网游服务器都会丢掉一些逻辑错误的包,除非服务器自己想挂掉,明知数据有错还去处理,这样的服务器程序我是不会要的。 另外一个,很多人都会想,玩家可能不干了,我明明打怪了,为什么打怪的动作没有?我想当一个网络状况不好的情况下,即使是TCP也会出现延迟的情况,玩家不会在意你这一下两下打了没反应,我不知道大家玩过网上的CS什么感觉,你确信你的每一次没打中对方的子弹都是因为你不准吗?我看未必,很多包都被同步掉了,你射出去的子弹只有在满足一定同步条件下才会被处理的。当然我刚才举的例子也很特殊,无序不会夸张到那种程度,另外一个就是我下面要讲的应用。 关于UDP的丢包处理。UDP丢包很多人的想法就是设置标签然后重发,那么这个是没有必要的,这种没有必要是在一定的特殊条件下:运动同步。如果你想要做运动同步,那么TCP将是非常臃肿的,因为每隔一段时间(一半都在半秒之内),玩家和服务器之间就需要交换一次空间参数(什么位置坐标,速度,方向,时间等等),大量的频繁的小数据包交换使用TCP将是可怕的(如果你不关掉延迟发送算法,那么很多数据都失去了意义)。这个时候UDP的特点就体现出来了,速度快,封包体积小,基于消息的。那么丢掉的包怎么办?很简单,丢就丢了呗,反正每隔半秒就会有新的修正数据发过来,你怕什么,如果你重发,发而不合时宜了,因为同步数据都是有时效性的,你重发的包往往失去了时效,没有意义了,所以不用重发,直接等待下一个新包吧 好了,就这么多了,欢迎大家指点
关于用UDP网络游戏服务器的一些探讨
比如说,玩家去攻击一个怪物,我们把它放大为2个消息,[走到怪物跟前] [攻击怪物]。如果采用TCP协议,那么消息是连续的,先做第一个动作[走到怪物跟前],再做第二个动作[攻击怪物]。如果是UDP协议,那么这个消息可能发生倒序,可能变成了先[攻击怪物],然后[走到怪物跟前],这样看来就有点怪怪的。这个问题如何解决呢,其实在处理包的时候有一个逻辑层,这个问题本来是一个网络传输层的错误,但是我们可以将它转化为一个逻辑层的错误,我们可以认为凡是在怪物一定范围之外的近身攻击都是无效的(我想大多数网游服务器段都是这样处理的,没有哪个网游的战士能拿武器老远打怪的),无效的消息如何处理?很简单,丢掉,呵呵。 可能很多人不同意我最后的处理办法,没有关系,我说过了,这只是一部分特定的网游可以这么做,另外一方面,大部分网游服务器都会丢掉一些逻辑错误的包,除非服务器自己想挂掉,明知数据有错还去处理,这样的服务器程序我是不会要的。 另外一个,很多人都会想,玩家可能不干了,我明明打怪了,为什么打怪的动作没有?我想当一个网络状况不好的情况下,即使是TCP也会出现延迟的情况,玩家不会在意你这一下两下打了没反应,我不知道大家玩过网上的CS什么感觉,你确信你的每一次没打中对方的子弹都是因为你不准吗?我看未必,很多包都被同步掉了,你射出去的子弹只有在满足一定同步条件下才会被处理的。当然我刚才举的例子也很特殊,无序不会夸张到那种程度,另外一个就是我下面要讲的应用。 关于UDP的丢包处理。UDP丢包很多人的想法就是设置标签然后重发,那么这个是没有必要的,这种没有必要是在一定的特殊条件下:运动同步。如果你想要做运动同步,那么TCP将是非常臃肿的,因为每隔一段时间(一半都在半秒之内),玩家和服务器之间就需要交换一次空间参数(什么位置坐标,速度,方向,时间等等),大量的频繁的小数据包交换使用TCP将是可怕的(如果你不关掉延迟发送算法,那么很多数据都失去了意义)。这个时候UDP的特点就体现出来了,速度快,封包体积小,基于消息的。那么丢掉的包怎么办?很简单,丢就丢了呗,反正每隔半秒就会有新的修正数据发过来,你怕什么,如果你重发,发而不合时宜了,因为同步数据都是有时效性的,你重发的包往往失去了时效,没有意义了,所以不用重发,直接等待下一个新包吧 好了,就这么多了,欢迎大家指点