其他答案都是相当高级的,这很好,但你不想要高级,你想要低级,比如“我如何让它真正发送数据,这意味着什么?我要发送什么,等等。”这是你要做的:
首先,TCP 还是 UDP?如果您不知道其中任何一个是什么,请阅读它们,因为我没有空间在这里对两者进行详细介绍,但您可以选择了解以下内容:
- TCP 适用于回合制游戏或高延迟通常可以接受的游戏,因为 TCP 保证数据包传送,因此重新传送丢弃的数据包可能需要一些时间。这对于国际象棋之类的东西或其他任何轮流的东西都有好处。
- UDP 适用于那些您不一定关心消息的可靠性并且希望数据只是不断发送的游戏,如果您错过了什么,哦,好吧。这适用于基于实时动作的游戏,例如《光环:致远星》或《使命召唤》。在那些情况下,如果您发送一个对象的位置,而该对象永远不会到达那里,则发送一个新位置比重新发送一个旧位置(现在更旧)更好,因此始终保证可靠性并不重要。也就是说,您必须让某些东西 100% 可靠,因此您仍然需要某些东西来保证交付,例如对象创建和对象销毁。这意味着您需要在 UDP 之上实现自己的半可靠、基于优先级的协议。这很难。
所以,问问自己什么是重要的,了解 TCP 和 UDP 的工作原理,然后做出明智的选择。
也就是说,现在您必须通过网络同步对象状态。这意味着您的对象需要序列化为可以在字节流中表示并写入套接字的东西。写入套接字很容易;如果您可以写入文件,您可以写入套接字,这真的不难。重要的是确保您能够将对象表示为缓冲区,因此如果您的对象具有指向其他对象的引用/指针,您将无法仅发送这些指针,因为它们在其他客户端上是不同的,因此您必须将它们转换为所有主机通用的东西。这意味着 ID,尽管一个对象的 ID 在所有主机中必须是唯一的,因此您必须有一种方法在主机之间进行协调,这样没有两个主机会创建具有相同 ID 的不同对象。有一些方法可以处理主机这样做,但我们不会在这里担心(提示:在主机 ID 和网络 ID 之间使用某种映射。更大的提示:如果不需要,请不要这样做)。
所以现在你可以发送数据了,太好了,现在怎么办?每次游戏状态发生变化时,您都必须以某种方式向其他机器发送更新。这就是客户端-服务器架构的用武之地,如果您愿意,也可以是对等架构。客户端-服务器更容易实现。此外,一台“充当”服务器的主机仍然是客户端-服务器,任何说不同的人都是错误的。
因此,服务器的责任是“拥有”所有游戏状态。只有服务器可以明确说明对象处于什么状态。如果要移动对象,请告诉服务器您要移动,但是服务器随后会告诉您应该移动对象,您不只是去做(尽管某种客户端预测通常很有用)。然后服务器将更新后的对象状态发送给所有其他主机。
那么,您提到了一款回合制游戏,对吧?很简单:
- 您将解决当前轮到客户端的完整轮到问题。一旦该客户端完成了他们想做的事情,将该轮次的结果发送到服务器。然后服务器验证客户端的动作(不要只信任客户端,作弊就是这样发生的)并将它们应用于其对象状态。
- 一旦服务器更新到最新状态,它就会向所有其他客户端发送消息,其中包含新的世界状态,并且这些客户端会应用这些更新。这包括刚刚轮到他们的客户;该客户端应该只在服务器告诉它时更新它的世界状态,因为你想确保与其他主机的一致性,并且你想防止主机作弊。
- 然后服务器发出一条消息,指示轮到谁了。您可以在上一步中与世界状态更新同时发送它,这很好。请注意客户试图让他们的轮到他们的秩序。这就是为什么服务器在世界范围内拥有权威的原因;如果客户端试图作弊,服务器可以将其击倒。
这就是回合制游戏所需要做的一切。提示:使用 TCP
更大的提示:TCP 实现了一种称为“Nagle 算法”的东西,它将您的消息组合成一个数据包。这意味着,如果您通过两次单独调用“Send”发送两条单独的消息,则其他主机可能会在一次调用“Receive”时仅收到一个数据包,但该数据包将包含发送的数据包。因此,如果您通过两次发送调用发送两个 100 字节的数据包,您可能会在一次接收调用中获得一个 200 字节的数据包。这是正常的,所以你需要能够以某种方式处理这个问题。一个技巧是使每个数据包的大小相同,然后每次检查输入时从套接字读取那么多字节。请记住,您也可能会收到部分消息。例如,如果您发送两条 100 字节的消息,它们可以组合成一条 200 字节的消息。接下来,如果您从另一端的套接字读取,但您读取的缓冲区大小为 150 字节,您将有 150 字节,其中包含第一个数据包和第二个数据包的一部分。您必须拨打第二个电话才能收到第二条消息的其余部分,因此请跟踪您收到的数据量,以免在某处丢失部分数据包。这就是为什么保持数据包大小相同的原因。
还有许多其他有用的技巧可以减少消息的大小和频率,以及跟踪非回合制和实时行动的游戏,但如果您有回合制游戏,那么正确的做法可能是使用 TCP 而不必担心其他任何东西。以下是一些有用的网站和文章的链接,它们将为您提供有关如何完成游戏网络编程的更多信息:
如果您想了解有关这些内容的更多详细信息,或者您有更具体的问题,请告诉我。