关于tcp:GAMEPROGRAMMING通过……进行客户端/服务器通信?

GAMEPROGRAMMING Client/Server communication through … ? (JAVA)

我有一个关于在网络游戏上编程客户机/服务器通信的一般问题。我使用TCP作为协议,并且通信…有效,但我不确定是否有效。

通常,在客户端发生的操作将经历以下所有步骤:

  • 一些动作(如发射火球)
  • [*]对于这个动作,我定义了一个字符串(例如,f 270 130,意思是"f"表示它是一个火球,270是(例如)角度的度数,130是射击火球的速度。)
  • 字符串进入客户端&waitingqueue的outputpuffer
  • 字符串已发送
  • 服务器接收到字符串
  • [*]服务器需要一个能检测字符串含义的lineexplorer(这里:什么是f?这是一个火球!)&;添加一个唯一标识,该标识基于从中接收命令的客户端。
  • [*]服务器需要根据所发生的操作计算逻辑(火球会对某人造成伤害,是否会立即击中某人,或者只是先飞?)
  • 服务器向所有客户端发送(更新的)操作字符串。(例如,由于某种原因,火球的速度可能会减慢-这里将有一个更新的字符串(f 12345 270 90-12345是唯一的玩家身份)
  • 客户端接收字符串
  • [*]客户端将字符串解析为命令+处理它(激发AnimationSequence…)
  • 最初发送该命令的客户机将接收到的字符串与等待队列中的字符串进行比较-如果相等,则不执行任何操作(以简化某些操作,否则通过连接问题/延迟,某些操作将发生两次或基于ping从位置跳到位置
  • 是否真的需要完成所有这些步骤?在所有标记为[*]的步骤中,我都需要为每个命令定义新的lineinterpreters/action,因此我将对每个操作进行两次编码,即客户端和服务器端。我读了一些关于发送可序列化对象的内容,但是在generial中,我的想法似乎是一样的,我发送一个对象,它必须被解释+处理,然后我发送一个对象回来…

    有什么提示吗?解决整个通信更优雅,编码更少?或者更分类一点-所有这些标记用于不同的操作,使其变得越来越复杂:)

    (实际上,我有以下处理程序/操作:

    -移动-观察/旋转-HP变更-火箭-生成/断开连接……)

    希望你明白我的意思-我知道,我可以继续这样编码,它会以某种方式工作,但它看起来太复杂了。

    谢谢!


    如果你:

  • Define an object called Action or something like that, which has all of the above parameters - type of action, direction of action (or
    target), damage dealt, etc..
  • Create those Action objects as your game normally executes
  • Use ObjectOutputStream chained to your TPC Socket to output the whole Action object to the server/ pass it back to the client.
  • On the server, interpret what happens by examining the recieved object from ObjectInputStream.
  • 我认为,如果您添加更多的逻辑,而不仅仅是分析字符串,而不是像分析字符串那样快(因为进入ObjectOutputstream的对象需要序列化),那么这种方法会更干净、更灵活。


    在决定游戏是否需要更改之前,您需要考虑几个因素。

    首先,TCP是最佳的通信通道吗?你把它和UDP比较过吗?使用UDP实现网络会更好吗?如果少了几个包裹有关系吗?如果网络速度慢怎么办?

    其次,看看您轮询/推送到服务器的频率。这个可以减少吗?游戏必须实时进行吗?做游戏的所有部分都必须是实时的。也许某些事情是非实时的。一个火球会沿着一条直线前进,所以你不必不断更新服务器的位置,你只需告诉它它的方向和速度。游戏的其他哪些方面可以是非实时的。唯一需要发送的是玩家的位置和动作。大多数其他事情,比如碰撞检测,都可以卸载到客户端。

    第三,每个按键都需要发送到服务器吗?如果用户靠墙并想进一步移动,客户机知道他们不能,因此不会将这些按键发送到服务器。如果用户已移动到新的有效位置,则更新服务器。可以一次性将某些内容缓冲并发送到服务器,而不是向服务器发送多个查询。也就是说,如果我向前移动,跳跃并投掷一个火球,这是客户端的3个按键,它们能在下一个500毫秒被缓冲并发送吗?

    如果你担心网络开销,你应该在比特级工作。不是发送一个长字符串"f 270 130"(11字节长),而是发送3个连续字节(24位)是否有意义。

    7位代表动作(127个不同动作)。9位表示角度(1-512),但最多只需要0-360度。8位代表力。

    这种或任何其他字节格式更短,更易于在网络上使用,并生成更紧密的代码。二进制比较也更快,因此现在在服务器上编写操作解析器变得更容易了。也就是说,与寻找f的大型开关盒不同,您只需查看前7位并将其与int进行比较。

    您是否可以减少其他网络开销,而不是由客户机强制决定,服务器是否可以决定这一点。即标准力或2级力(最好用1位表示)。这就阻止了客户端和恶意用户向服务器发送垃圾数据(比如强制999),现在强制可以是0或1,即速度为10或20,没有什么愚蠢的。