我有一个TCP服务器和客户端,有一个既定的插座。 比方说,我有以下情况:
服务器:
char *fn = "John";
char *ln = "Doe";
char buffer[512];
strcpy(buffer, fn);
send(*socket, buffer, strlen(buffer), 0);
strcpy(buffer, ln);
send(*socket, buffer, strlen(buffer), 0);
客户:
char *fn;
char *ln;
char buffer[512];
bytes = recv(*socket, buffer, sizeof(buffer), 0);
buffer[bytes] = '\0';
strcpy(fn, buffer);
bytes = recv(*socket, buffer, sizeof(buffer), 0);
buffer[bytes] = '\0';
strcpy(ln, buffer);
printf("%s", fn);
printf("%s", ln);
预期结果:我想单独接收每个字符串(因为我节省了他们在不同的变量),而不是第一的recv()获取两个FN“约翰”和LN“李四”串联“JOHNDOE”,并且程序卡住上第二的recv()......因为我已经做了发送。
我试过如下: - 添加\ 0到FN和LN的字符串,像这样:
char *fn = "John\0";
char *ln = "Doe\0";
但问题依然存在。
是否有某种条件我可以并处所以每个字符串单独接收?
编辑补充更多的问题:
1)为什么它在某些情况下,实际上分别给他们,和其他人将它们发送联合?
2)我应该向()和recv()或者可能? 在我的代码其他一些地方,现在看来,这是自我调节,只接收在正确的时间正确的字符串没有我不必检查。 这是否做的伎俩?
3)关于发送带有我即将发送字符串长度的头,我该如何解析输入字符串知道从哪里分割? 任何例子将是巨大的。
4)我一定会检查,如果我得到的东西大于我的缓冲区,感谢指向它。
编辑2:
5)由于我总是把事情尺寸512的缓冲字符数组不应该每次发送操作把缓冲区的全尺寸即使我发送1个字母串? 这就是混乱。 我有“约翰”,但我把它的大小为512的数组和发送它,应该不是填满发送缓冲区,所以的recv()函数也拉动尺寸全阵列清空网络缓冲区512?
首先,当客户端调用recv(*socket, buffer, sizeof(buffer), 0);
,它将从网络接收到的sizeof(缓冲液)的字符(在这里,512)。 这是从网络缓冲区,并有无关多少次send
被称为服务器上。 recv
不查找\0
或任何其他字符-它是由网络缓冲区二进制拉。 它将读取整个网络缓冲液或sizeof(buffer)
的字符。
您需要在第一个检查recv
,看它是否有两个姓和名,并适当地处理它。
可以通过具有该服务器发送该串的长度作为流的前几个字节(一个“头”),或者通过扫描所接收的数据,以查看是否有两个字符串这样做任一。
你真的需要执行检查时,你打电话recv
-如果该字符串的长度超过512个字节? 然后,你需要调用recv
多个时间STO得到的字符串。 如果你得到了什么第一个字符串,第二个字符串的只有一半? 通常这两种情况有更大量的数据的时候才会发生,但我已经看到它在我自己的代码之前发生的,所以这是最好地将上好的支票recv
像这样的小弦打交道时也是如此。 如果你养成良好的编码策略早,你会不会有很多头痛的道路。
做正确的事情是有头围发送的数据。 所以,你会通过邮件的大小,包括邮件的大小,然后在另一边,你可以计算出该消息应该有多长。
约翰是4个字符,所以你必须长度,如“0004John”的东西,那么你会知道什么时候停止阅读。 您可能还需要一个命令添加到头部,这是非常普遍的。 因此,例如,名字可能是1,二名2;
“01004JOHN”比如将在缓冲区和发送进行设置。
要做到这一点,将项目添加到缓冲区中,然后由你的sizeof添加值增加在缓冲区中插入点。 您可以使用此许多部件添加到缓冲区。 *只要确保你不溢出缓冲区的大小。
请记住这些例子IM捐赠是不正确的,因为你不通过数字的字符串表示,只是数量,所以这将是一个长整型1,长整型4个,然后字符或Unicode,无论哪种方式,4个字符。
TCP是面向流的,不是数据报为主。 如果是后者,你的东西会工作的伟大。 您有以下选择:
- 使用SCTP
- 使用UDP,如果你能承受失去可靠性
- 在某种程度上,你可以在前面加上长度标记左右或者通过添加一起工作,分隔字符串
NUL
终止每串字节。
对于后者,你只需做send(*socket, buffer, strlen(buffer)+1, 0);
对于包括NUL
是这里然而,并且发件人会反复recv()
并找到一个字符串结束,直到它找到2串。
请注意,您应该注意用strcpy()
只使用它,如果你绝对相信你正在写的字符串是确定的。
您的接收器确实
bytes = recv(*socket, buffer, sizeof(buffer), 0);
buffer[bytes] = '\0';
这是不好的,因为,如果缓冲区已满,所以bytes == sizeof(buffer)
(可在更复杂的情况发生), buffer[bytes] = '\0'
写入超出缓冲区。 所以使用
bytes = recv(*socket, buffer, sizeof(buffer) - 1, 0);
你可以愉快地做
buffer[bytes] = '\0';
。
代替的sizeof(缓冲液)使用strlen(FN); 所以只传输字节的确切数额。如果您需要空终止一起使用strlen(FN)+1,但不要忘了串联空终止与strcat的()
此外,如果你把所有的缓冲区大小不与memset的清洁你也有垃圾一起,所以要小心的..