Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用客户机-服务器体系结构在游戏中高效地发送对象_C#_Networking_Server_Xna_Tcpclient - Fatal编程技术网

C# 如何使用客户机-服务器体系结构在游戏中高效地发送对象

C# 如何使用客户机-服务器体系结构在游戏中高效地发送对象,c#,networking,server,xna,tcpclient,C#,Networking,Server,Xna,Tcpclient,我制作了一个网络2d自上而下的射击游戏。这是相当标准的,用户使用WASD移动他们的玩家,并且可以使用12345和鼠标施法。用户必须杀死敌人并保持生存 我已经为多个用户在同一个竞技场进行了联网,但运行起来效率太低 精灵存储在字典中,字典存储在客户端和服务器机器中 它的实施方式如下: 用户的键盘和鼠标输入会在每一帧发送到服务器(KeyboardState,MouseState) 服务器接收输入并更新游戏状态 服务器向每个客户端发送其视口(矩形),以及该用户视口中所有精灵的位置(浮点、浮点)、精灵键(

我制作了一个网络2d自上而下的射击游戏。这是相当标准的,用户使用WASD移动他们的玩家,并且可以使用12345和鼠标施法。用户必须杀死敌人并保持生存

我已经为多个用户在同一个竞技场进行了联网,但运行起来效率太低

精灵存储在
字典中,字典存储在客户端和服务器机器中

它的实施方式如下:

  • 用户的键盘和鼠标输入会在每一帧发送到服务器(
    KeyboardState
    MouseState
  • 服务器接收输入并更新游戏状态
  • 服务器向每个客户端发送其视口(矩形),以及该用户视口中所有精灵的位置(浮点、浮点)、精灵键(字符串)、旋转(浮点)、颜色(int、int、int、int)
  • 服务器将此信息存储为保存这些值的类的实例
  • 要发送它,服务器使用
    BinaryFormatter
    序列化类,并使用
    TcpClient
    Sockets
    发送它
  • 客户端将传入的数据反序列化回类中,并将它们绘制到屏幕上
  • 不幸的是,这使得游戏速度非常慢。我只在一台机器上测试了这个,所以没有延迟,所以我假设发送的数据太多了

    要解决这个问题,我想我要么需要高效地存储和发送数据,要么以不同的方式实现

    为了高效地发送数据,我想我需要将数据打包为字节并发送,但我不知道如何做到这一点


    如何有效地发送数据,或以不同的方式实现数据以使其高效?

    尽量减少网络中的数据量。只发送所需数量的数据,并通过时间戳和验证提供您自己的验证

    下面的每个actionId和AnimationId应该显示最小(2的幂)字节量,以唯一地描述所有可能的值


    服务器->客户端:

    服务器知道客户端的位置和轮换。确认最后一个actionId。 所有其他客户端位置、方向(旋转)、动画ID的列表。。。在客户端的视野范围内+-maxRotationRate在MaxViewDistance+-maxMovementRate的距离内

    客户端必须在每一步将其当前位置与服务器位置平均

    本地处理所有输入(鼠标和键盘),仅向服务器发送相关数据:

    每次更新,客户机都会发送相关数据并更新自己的内部状态,处理给定的服务器状态,并增加int值(称为时间戳)。这里包括奇偶校验或CRC


    客户端->服务器 当前位置、旋转、actionId、animationId和单调递增的int值(称之为时间戳)。这里包括奇偶校验或CRC

    所有渲染决策、视口、当前动画/精灵/颜色都应在客户端上建立(颜色和初始位置需要在登录时提供给客户端)

    将共享位置数据(本地更新和服务器调整)

    每次更新都需要将位置、旋转和速度数据(线性和旋转)发送到服务器。在服务器上收到后,必须进行验证过程以防止作弊。在更新丢失、无序或格式错误时,服务器将采用上一个位置+速度*(与上一个时间戳的时间差+当前服务器时间)


    您必须使用UDP进行通信(请注意,您使用自己的时间戳和CRC来验证接收到的数据,无效数据不再崩溃)

    仅处理奇偶校验/CRC校验通过的数据包,并拒绝接收太短或校验失败的数据包。这些检查将消除与坏数据包相关的崩溃

    TCP的重试机制和有序交付对游戏性能有害。每次一个数据包丢失或无序交付时,由于服务器重试和数据包重新排序,时间增量错误(发送数据的时间与服务器处理数据的时间)增加RTT(往返时间,即Ping时间)。这将导致几秒钟的延迟,而延迟只会随着游戏的进行而增加

    网络延迟和丢失/格式错误的数据包是游戏中常见的情况。在基于时间戳值的无序数据包的情况下,删除除最后一个以外的所有数据包,因为这表示玩家的最新愿望(移动)。射击时(在你的情况下施法),持续发送法术位直到确认(ActionId)。忽略服务器上除第一个收到的咒语以外的所有咒语(向客户端发送确认),直到充值期结束


    虽然此答案排除了原始问题中未提出的所有要点,主要是损坏,但应创建一个结构,当损坏诱发元素的发生率在服务器上产生时,根据定义的损坏分布规则分配损坏,这需要应用到每个受影响的客户端。

    将通过网络的数据量降至最低。只发送所需数量的数据,并通过时间戳和验证提供您自己的验证

    下面的每个actionId和AnimationId应该显示最小(2的幂)字节量,以唯一地描述所有可能的值


    服务器->客户端:

    服务器知道客户端的位置和轮换。确认最后一个actionId。 所有其他客户端位置、方向(旋转)、动画ID的列表。。。在客户端的视野范围内+-maxRotationRate在MaxViewDistance+-maxMovementRate的距离内

    客户端必须在每一步将其当前位置与服务器位置平均

    处理所有