6

使用recv通过套接字接收数据时,我注意到:

字符缓冲区[4];
memset(缓冲区, 0, 4);
recv(socket, 缓冲区, 4, 0);

我收到

消息

“mesg”是我发送的,附加了一些随机字符。

如果我使用

char * 方法 = (char *) malloc(4);
memset(缓冲区, 0, 4);
recv(socket, 缓冲区, 4, 0);

相反,我收到

消息

所以没有随机的东西附加到我的字符串中。我发现如果我使用 char[5] 代替它也可以,但我真的不明白为什么。malloc(4) 真的分配了 5 个字节,第五个是 NUL 吗?

4

4 回答 4

16

调用malloc(4)真的只分配四个字节。巧合的是,内存中的下一个字节恰好是 NUL,它为您终止了您的字符串。

在您在堆栈上分配的情况下char buffer[4],下一个字节恰好是一个'x'紧随其后的其他东西,所以您的字符串一直持续到它找到下一个 NUL 字节。

套接字函数仅处理字节,并且不将字节视为带有尾随 NUL 或任何额外内容的字符串。你得到你所要求的。

于 2009-07-26T22:08:11.960 回答
6

您需要 5 个字符才能正确以 NULL 结尾。终止的 NULL 计为 1,因此如果我们需要 N 个字符,则分配 N+1。或者相反,对于 N 的分配,您有 N-1 可用于您的内容。

于 2009-07-26T22:02:45.607 回答
3

我怀疑这种差异是巧合。当您将缓冲区用作字符串时,例如在 printf() 中,它将被读取超过它的限制,直到找到 '\0'。

在这两种情况下,您都应该使用 buffer[5] 或 malloc(5)。memset() 不是必需的,最好在 recv() 之后放置一个 buffer[4] = '\0'。

于 2009-07-26T22:10:52.860 回答
2

您不可能收到超过 4char秒,因为您只要求recv将最多 4 个字节放入缓冲区。您应该检查返回值recv以查看实际返回了多少字节。

我怀疑问题在于您不小心只char从生成输出的任何例程中输出 4 秒。显示可能非空终止char缓冲区的初始内容的一种方法是这样。

printf("%.4s\n", buffer);

一个完整的recv调用片段可能是:

#define MAX_BUF_LEN (512)
char buffer[MAX_BUF_LEN];
ssize_t count = recv(socket, buffer, MAX_BUF_LEN, 0);

if (count > 0)
    printf("%.*s\n", count, buffer);
于 2009-07-26T22:09:09.367 回答