使用recv通过套接字接收数据时,我注意到了:
char buffer[4]; memset(buffer, 0, 4); recv(socket, buffer, 4, 0);
我收到了
mesgx
“mesg”是我发送的内容,附加了一些随机字符。
如果我使用
char * method = (char *) malloc(4); memset(buffer, 0, 4); recv(socket, buffer, 4, 0);
相反,我收到了
MESG
因此我的字符串中没有随机内容。我想出如果我使用char [5]而不是它也可以,但我真的不明白为什么。 malloc(4)真的分配了5个字节,第五个是NUL吗?
答案 0 :(得分:16)
对malloc(4)
的调用实际上只分配了四个字节。巧合的是,内存中的 next 字节恰好是NUL,它终结了你的字符串。
如果您在堆栈上分配了char buffer[4]
,则下一个字节恰好是'x'
,后跟其他一些东西,所以您的字符串会一直持续到找到下一个NUL字节为止。< / p>
套接字函数仅处理字节,并且不将字节视为具有尾随NUL的字符串或任何额外的字符串。你得到了你所要求的。
答案 1 :(得分:6)
您需要5个字符才能正确地以NULL结尾。终止NULL计为1,因此如果我们需要N个字符,则分配N + 1。或者相反,对于N的分配,您的内容可以使用N-1。
答案 2 :(得分:3)
我怀疑差异是巧合。当您使用缓冲区作为字符串时,例如在printf()中,它将被读取超过它的限制,直到找到'\ 0'。
在这两种情况下都应该使用buffer [5]或malloc(5)。 memset()不一定是必需的,最好在recv()之后放一个缓冲区[4] ='\ 0'。
答案 3 :(得分:2)
由于您只询问char
最多4个字节要放入缓冲区,因此您不可能收到超过4 recv
秒。您应该检查recv
的返回值,以查看实际返回的字节数。
我怀疑问题是你不小心只从生成输出的任何例程输出4 char
s。显示可能非空终止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);