我有一个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“John”和ln“Doe”并置为“JohnDoe”,并且该程序卡在了第二个recv上()...,因为我已经完成了发送。

我尝试了以下方法:
-在fn和ln字符串中添加\0,如下所示:
char *fn = "John\0";
char *ln = "Doe\0";

但是问题仍然存在。

我可以施加某种条件,以便分别接收每个字符串吗?

编辑以添加更多问题:

1)为什么在某些情况下实际上将它们单独发送,而其他情况则将它们共同发送?

2)我应该send()和recv()交替吗?在我的代码的其他部分,这似乎是自我调节的,并且仅在正确的时间接收正确的字符串,而无需我检查。这能达到目的吗?

3)关于发送带有我要发送的字符串长度的 header ,如何解析传入的字符串以知道在哪里拆分?任何例子都很好。

4)我肯定会检查我是否得到比缓冲区更大的东西,感谢您指出它。

编辑2:

5)因为我总是把东西放在大小为512的缓冲区char数组中。即使我发送的是1个字母的字符串,每个发送操作也不应该占用缓冲区的全部大小吗?那真是令人困惑。我有“John”,但我将其放入大小为512的数组中进行发送,不应该填满发送缓冲区,因此recv()函数也通过拉取整个大小的数组来清空网络缓冲区512?

最佳答案

首先,当客户端调用recv(*socket, buffer, sizeof(buffer), 0);时,它将从网络接收多达sizeof(buffer)个字符(此处为512)。这来自网络缓冲区,与在服务器上调用send的次数无关。 recv不会查找\0或任何其他字符-它是从网络缓冲区中提取的二进制文件。它将读取整个网络缓冲区或sizeof(buffer)字符。

您需要 checkin 第一个recv来查看它是否同时具有名字和姓氏,并进行适当的处​​理。

您可以通过使服务器将字符串的长度作为流的前几个字节(“ header ”)发送,或者通过扫描接收到的数据以查看是否有两个字符串来做到这一点。

每当调用recv时,您实际上都需要执行检查-如果字符串长于512个字节,该怎么办?然后,您需要多次调用recv来获取字符串。如果得到第一个字符串,而只有第二个字符串的一半,该怎么办?通常,这两种情况仅在处理大量数据时才会发生,但是我之前已经在我自己的代码中看到过,因此即使在处理像这样的小字符串时,最好也对recv进行良好的检查。如果您尽早练习良好的编码策略,那么您将不会有太多麻烦。

10-02 07:26
查看更多