2012-08-01 26 views
0

即时通讯新的套接字,我在网上创建一个tictactoe,我知道如何建立与客户端和服务器的连接,但我也会聊天。C#最好的方式来区分套接字消息

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

THX !!!

+1

你总是可以使用两个套接字。 – Littlegator 2012-08-01 19:19:33

回答

2

在通过像TCP的基于流的协议限定了线协议,则有用于构造消息的几个选项:

  • 固定长度
    • 所有消息都是相同的长度;每个x字节的序列代表一个新的消息。
  • 长度前缀(可变长度)
    • 消息的第一个字节(一个或多个)表示有效负载跟随的长度。
  • 字符串终止(可变长度)
    • 阅读来自该流的字节,直到出现一个表示消息的结束的特定字节串,即换行符\n

如果你打算在改变协议(普罗蒂普:你会的,即使你不认为你会),这是至关重要的,你包括协议版本每封邮件中的标识符使用协议的旧版迭代来处理客户时防止出现问题。显然,这是在解密剩余有效负载之前首先必须确定的,因此这应该是消息的第一个字节(在任何长度前缀之后) - 如果我们不这样做,我们如何确定版本知道我们收到的每条消息的位置在

1

需要定义一个协议。请记住为更多功能提供空间:-)。

例如,使用过完整线(端与选定行终止子)的正则表达式:

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

和其他任何东西(在V1中)是错误的。

记住:

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

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

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

该类型可以用代码表示为enum。长度将仅表示有效负载的长度。

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

我假设你使用的是TCP?

您需要确保将两个消息“框起来”,以便您可以识别它们并避免潜在的阻塞问题(如果客户端在您仍然期望读取CHAT时停止发送或您定义的任何内容)。使用TCP,你的字节顺序是有保证的,但是读取并不能保证一个完整的'数据包',所以你需要实现一些建立缓冲区和识别你的'消息'完成的方式。

这样做的一个合理简单的方法是确保每个'消息'有一个指定类型和大小的头。

EG:

枚举您的消息类型(移动,目前聊天),所以说“聊天”为0x01,你的消息是1020个字节。你可以用0x0103FC作为你的'消息'的前缀,这样服务器就知道有多少字节可以预期,并且使用异步套接字调用来建立一个缓冲区,直到读取1020字节(或者你随意决定客户端不再发送)

相关问题