2010-12-11 59 views
2

我遇到了一个有趣的C套接字问题。C套接字 - 一次随机接收多个字符串

我正在接收传入的字符串,并注意到我会随机接收3个字符串,同时为第2〜4个字符串。

例如,我收到以下传入字符串。

1~message~i love you\r\n 
2~message~do you love me?\r\n 
3~message~when are we going to meet again?\r\n 
4~message~How about now?\r\n 
5~message~Oh! I'm pregnant!\r\n 

我添加了一个计数器来跟踪所接收的消息的数量,并注意到计数器有时不计算所述第一3个字符串。例如

1~message~i love you\r\n 
->Line 1 received 
2~message~do you love me?\r\n 
3~message~when are we going to meet again?\r\n 
4~message~How about now?\r\n 
->Line 2 received 
5~message~Oh! I'm pregnant!\r\n 
->Line 3 received 

以下是我对打印行数

int lineNo = 1; 
while ((recvBytes = recv(clntSockfd, buffer, sizeof(buffer), 0)) > 0) { 
    printf("%s", buffer); 
    memset(&buffer, 0, sizeof(buffer)); 
    printf("Line %d received\n", lineNo++); 
} 

我不知道为什么会这样,因为当我用Java NIO编码这个问题没有出现代码。

任何想法,乡亲?

回答

0

你使用什么连接类型?

UDP在大多数情况下是不可靠的。

就可靠性而言,TCP比UDP好得多。

+0

嘿Neilvert,我正在使用TCP。 – Poliquin 2010-12-11 15:36:42

1

您没有阅读到行尾。 buffer可以包含多行

8

假设您使用TCP,将recv()调用与您的案例中的“消息”(或“行”)相关联是有缺陷的。 TCP在概念上是一个字节流。发送操作系统可以将多个send()调用分组为单个IP数据包,接收操作系统可以自由报告多个传入数据包为单个recv()调用(假设缓冲区足够大)。它甚至可以选择通过recv呼叫拆分传入数据包。

所以,你真的需要在数据本身,例如消息结构。通过扫描接收到的数据中的换行符。

Java中没有发生这种情况是纯粹的运气。

+0

在回送过程中,您倾向于获取发送大小的数据包。然而,在真实网络中,这很难避免合并数据包。如果发送数据包的间隔时间大约为100 ms,则通常会按照它们发送的大小获取数据包,但不应该依赖此行为。 – 2010-12-11 11:00:46

+0

嘿家伙,谢谢你的抬头。我想我会像马丁建议的那样扫描换行符。我在晚餐时一直在想它。现在我回来了,可能会更多一点。看着strtok()和strtok_r()。 strtok_r()看起来更好,因为文档说它对线程有好处。此外,我打算将字符串“1〜信息〜我爱你\ r \ n”分解为“1”“信息”“我爱你”的每个标记。 – Poliquin 2010-12-11 15:40:14