Jas*_*zek 17 c# sockets client-server
我试图更好地理解c#中的tcp/ip套接字,因为我想挑战自己,看看我是否可以创建一个有效的MMO基础设施(游戏世界,地图,玩家等)纯粹用于教育目的,因为我没有意图成为另一个"OMGZ iz将让我的r0x0r MMORPG比魔兽更好!!!",你知道我在说什么.
无论如何,我想知道是否有人可以阐明一个人如何设计这种系统以及需要什么样的东西,以及我应该注意什么?
我最初的想法是将系统分解为单独的客户端/服务器连接,每个连接(在自己的端口上)执行特定任务,例如更新玩家/怪物位置,发送和接收聊天消息等等.处理数据更容易,因为您不总是需要在数据上放置标题以了解数据包包含哪些信息.
这是否有意义且有用,还是我只是简单地复杂化了事情?
非常感谢您的回复.
gri*_*eve 30
如果您正在进行套接字级编程,那么无论您为每种消息类型打开多少端口,您仍然需要具有某种类型的标头.即使它只是消息其余部分的长度.已经说过很容易为消息添加简单的头和尾结构.我认为只需处理客户端的一个端口就更容易了.
我相信现代MMORPG(甚至可能是旧版)有两级服务器.登录服务器验证您是付费客户端.一旦验证,这些将您带到包含所有游戏世界信息的游戏服务器.即便如此,这仍然只需要客户端打开一个套接字,但不允许有更多.
此外,大多数MMORPGS还加密他们的所有数据.如果你把它写成一个有趣的练习,那么这并不重要.
一般来说,设计/编写协议是我担心的事情:
字节序
客户端和服务器是否始终保证具有相同的endianess.如果不是,我需要在序列化代码中处理它.有多种方法可以处理结束.
在我通常选择2的4中,并指定endianess为大多数客户端,现在几天将是小端.
前向和后向兼容性
协议是否需要向前和向后兼容.答案应该几乎总是肯定的.在这种情况下,这将决定我如何在版本控制方面设计整个协议,以及如何创建每个单独的消息来处理实际上不应该成为版本控制的一部分的微小更改.你可以利用这个并使用XML,但是你会失去很多效率.
对于整体版本控制,我通常设计一些简单的东西.客户端发送一个版本控制消息,指出它说的是版本XY,只要服务器可以支持该版本,它就会发回一条确认客户端版本的消息,一切都在前进.否则它会解密客户端并终止连接.
对于每条消息,您可以使用以下内容:
+-------------------------+-------------------+-----------------+------------------------+
| Length of Msg (4 bytes) | MsgType (2 bytes) | Flags (4 bytes) | Msg (length - 6 bytes) |
+-------------------------+-------------------+-----------------+------------------------+
Run Code Online (Sandbox Code Playgroud)
长度显然告诉你消息有多长,不包括长度本身.MsgType是消息的类型.这只有两个字节,因为65356是应用程序的大量消息类型.标志是为了让您知道消息中序列化的内容.此字段与长度相结合,为您提供向前和向后兼容性.
const uint32_t FLAG_0 = (1 << 0);
const uint32_t FLAG_1 = (1 << 1);
const uint32_t FLAG_2 = (1 << 2);
...
const uint32_t RESERVED_32 = (1 << 31);
Run Code Online (Sandbox Code Playgroud)
然后您的反序列化代码可以执行以下操作:
uint32 length = MessageBuffer.ReadUint32();
uint32 start = MessageBuffer.CurrentOffset();
uint16 msgType = MessageBuffer.ReadUint16();
uint32 flags = MessageBuffer.ReadUint32();
if (flags & FLAG_0)
{
// Read out whatever FLAG_0 represents.
// Single or multiple fields
}
// ...
// read out the other flags
// ...
MessageBuffer.AdvanceToOffset(start + length);
Run Code Online (Sandbox Code Playgroud)
这允许您在消息末尾添加新字段,而无需修改整个协议.它还确保旧服务器和客户端将忽略他们不知道的标志.如果他们必须使用新的标志和字段,那么您只需更改整个协议版本.
使用框架工作与否
我会考虑将各种网络框架用于业务应用程序.除非我特别需要划伤,否则我会使用标准框架.在您的情况下,您想学习套接字级编程,所以这是一个已经为您解答的问题.
如果确实使用了框架,请确保它解决了上述两个问题,或者至少在您需要在这些区域进行自定义时不会妨碍您.
我与第三方打交道吗?
在许多情况下,您可能正在处理需要与之通信的第三方服务器/客户端.这意味着一些场景:
在任何一种情况下,您都不会与第三方合作,所以这只是为了完整性而添加的.
我觉得好像我可以写更多关于这个,但它已经相当冗长.我希望这有帮助,如果您有任何具体问题,请在Stackoverflow上询问.
编辑回答knoopx的问题:
| 归档时间: |
|
| 查看次数: |
9987 次 |
| 最近记录: |