分别发送和接收的字符串在TCP套接字(Sending and receiving strings o

2019-08-03 09:28发布

我有一个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?

Answer 1:

首先,当客户端调用recv(*socket, buffer, sizeof(buffer), 0); ,它将从网络接收的sizeof(缓冲液)的字符(在这里,512)。 这是从网络缓冲区,并有无关多少次send被称为服务器上。 recv不查找\0或任何其他字符-它是由网络缓冲区二进制拉。 它将读取整个网络缓冲液或sizeof(buffer)的字符。

您需要在第一个检查recv ,看它是否有两个姓和名,并适当地处理它。

可以通过具有该服务器发送该串的长度作为流的前几个字节(一个“头”),或者通过扫描所接收的数据,以查看是否有两个字符串这样做任一。

你真的需要执行检查时,你打电话recv -如果该字符串的长度超过512个字节? 然后,你需要调用recv多个时间STO得到的字符串。 如果你得到了什么第一个字符串,第二个字符串的只有一半? 通常这两种情况有更大量的数据的时候才会发生,但我已经看到它在我自己的代码之前发生的,所以这是最好地将上好的支票recv像这样的小弦打交道时也是如此。 如果你养成良好的编码策略早,你会不会有很多头痛的道路。



Answer 2:

做正确的事情是有头围发送的数据。 所以,你会通过邮件的大小,包括邮件的大小,然后在另一边,你可以计算出该消息应该有多长。

约翰是4个字符,所以你必须长度,如“0004John”的东西,那么你会知道什么时候停止阅读。 您可能还需要一个命令添加到头部,这是非常普遍的。 因此,例如,名字可能是1,二名2;

“01004JOHN”比如将在缓冲区和发送进行设置。

要做到这一点,将项目添加到缓冲区中,然后由你的sizeof添加值增加在缓冲区中插入点。 您可以使用此许多部件添加到缓冲区。 *只要确保你不溢出缓冲区的大小。

请记住这些例子IM捐赠是不正确的,因为你不通过数字的字符串表示,只是数量,所以这将是一个长整型1,长整型4个,然后字符或Unicode,无论哪种方式,4个字符。



Answer 3:

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';



Answer 4:

代替的sizeof(缓冲液)使用strlen(FN); 所以只传输字节的确切数额。如果您需要空终止一起使用strlen(FN)+1,但不要忘了串联空终止与strcat的()

此外,如果你把所有的缓冲区大小不与memset的清洁你也有垃圾一起,所以要小心的..



文章来源: Sending and receiving strings over TCP socket separately
标签: c sockets tcp