C#区分套接字消息的最佳方法

时间:2012-08-01 14:31:41

标签: c# sockets

我是套接字的新手,我在网上创建了一个tictactoe,我知道如何与客户端和服务器建立联系,但我也会聊聊。

然后我这样做,当用户聊天时我发送带有前缀“CHAT:HELLO WORLD”的消息 当用户移动时我发送一条没有前缀的消息......这是最好的方法吗?

THX !!!

4 个答案:

答案 0 :(得分:3)

通常,您会使用包含数据包长度,类型和有效负载的格式。

在你的情况下,你可以使用字节(类型),Int16(长度),字节[](有效载荷)。

该类型可以在代码中表示为枚举。长度只表示有效载荷的长度。

public enum Byte PacketType {
  PlayerMove = 1,
  PlayerChat = 2
}

答案 1 :(得分:2)

在基于流的协议(如TCP)上定义有线协议时,您可以使用以下几种方法来构建消息:

  • 固定长度
    • 所有消息长度相同;每个x字节序列代表一条新消息。
  • 长度为前缀(可变长度)
    • 消息的第一个字节表示要遵循的有效负载的长度。
  • 字符串终止(可变长度)
    • 从流中读取字节,直到找到表示消息结尾的指定字节字符串,即换行符\n

如果您打算更改协议(protip:即使您认为不会,也会这样),在每条消息中包含协议版本的标识符以防止在处理客户端时出现问题至关重要使用较旧的协议迭代。显然,这是在解密其余有效负载之前必须确定的第一件事,因此这应该是消息的第一个字节(跟随任何长度前缀) - 如果我们不这样做,我们怎么能确定版本知道我们收到的每条消息中的位置?

答案 2 :(得分:1)

需要定义协议。请记住留出额外功能的空间: - )。

EG。在整行上使用正则表达式(以选定的行终止符结束):

  • 匹配^:[a-c][1-3]::是一个移动(冒号,位置,冒号用户名)。
  • 匹配^!.*?::是一条聊天消息(感叹号,名称,冒号,文字)。

以及其他任何内容(在V1中)都是错误。

记住:

  • 数据以数据包形式发送,您可能需要从套接字进行多次读取才能获得完整的消息。
  • 避免含糊不清:解决它可能是x或y很难。
  • 指定文本编码(例如UTF-8)。

答案 3 :(得分:0)

我假设您正在使用TCP?

您需要确保“框架”两条消息,以便您可以识别它们并避免潜在的阻塞问题(如果客户端在您仍然希望阅读CHAT时停止发送:或者您定义的任何内容)。使用TCP,您的字节顺序是有保证的,但读取并不能保证完整的“数据包”,因此您需要实现某种方式来构建缓冲区并确定何时“消息”完成。

这样做的一个相当简单的方法是确保每个“消息”都有一个指定类型和大小的标题。

EG:

枚举你的消息类型(当前移动和聊天),所以说'chat'是0x01,你的消息是1020字节。您可以使用0x0103FC为“消息”添加前缀,以便服务器知道预期的字节数,并使用异步套接字调用构建缓冲区,直到读取1020个字节(或者您随意决定客户端不再发送)