在c中读取流套接字上的消息

时间:2012-12-18 11:33:50

标签: c sockets streaming

我正在编写客户端服务器模型应用程序,服务器在与客户端的流连接上以非常高的速率发送大量消息(具有不同大小),客户端在大于预期消息的缓冲区上读取这些消息大小

while (ret = read (sd, buf, sizeof buf) > 0)
{
      // decode message here
}

这里的问题是客户端可能会在缓冲区上读取多条消息,如果我认为缓冲区是B且消息是M#,它将收到如下消息

| ----乙---- | ----乙---- | ----乙---- | ----乙---- | ....

| -M1-- | -M2- | --M3- | -M4- | --- --- M5 | --M6- | ....

使得消息的解码不正确。所以,我希望收到如下消息(每个缓冲区只有一条消息)

| ----乙---- | ----乙---- | ----乙---- | ----乙---- | ....

| -M1-- | ,, | -M2- | ,,, | --M3- | ,, | -M4- | ....(,,,什么都没有,仅用于格式化)

注意到,我必须使用流连接,我不喜欢在消息之间不使用任何分隔符

2 个答案:

答案 0 :(得分:3)

您无法控制流的字节如何传递到应用程序,它是字节流,而不是单个消息。

即使你没有“喜欢”分隔符,这也正是为什么它们经常被使用的原因。这不是一个有趣的想法,它是解决这个问题的基本方法。反对意见不是“喜欢”它不是很有趣。

除了分隔符之外,你唯一的希望是实现消息解析,它可以在任何时候正确地确定它是否有完整的消息,如果是,那么是哪个消息。如果消息是“前缀”;因此,特定的字节序列B可以是完整的消息M1和M2的开始,那么我认为你是敬酒。

答案 1 :(得分:1)

有许多类型的分隔符。无论你的协议中的“非法”字符是什么,都会成为一个很好的分隔符,但如果你能选择一个可打印的字符,使得协议在嗅探器中更易读或者使用telnet。

基于XML或类似结构化数据的协议也是一种选择。这会产生更复杂的分隔符。

二进制协议通常使用TLV(http://en.wikipedia.org/wiki/Type-length-value),其中length指定消息中的字节数(仅限值部分或类型,长度和值) )。