从套接字读取缓冲区
我在c中编写简单的服务器/客户端,其中server临时存储来自客户端的消息,并在客户端请求时检索它。
问题是当客户端从服务器接收消息时,缓冲区行为有点奇怪。 我所做的只是从服务器接收并在屏幕上打印它,但不知何故缓冲区被覆盖超过最大缓冲区大小
在客户端
while((byteRead = recv(ssock, buffer, MAXBUF, 0)) > 0) { if(byteRead <= 0) break; printf("%s", buffer); }
其中MAXBUF是256.它保留了一些垃圾,所以我检查了缓冲区中的字符串大小,令人惊讶
printf("%d READ vs %d buffer strlen \n", byteRead, strlen(buffer))
告诉我byteRead是256但缓冲区的字符串长度是262。
任何的想法??
服务器端的Ps,它正确读取文件并将其发送到套接字。
recv
不会在字符串的末尾放置一个空终止符(而printf
%s
假定有一个)。
您必须使用byteRead
来确定字符串的长度。 如果要使用类似printf
,请添加一个null终止符,但要确保即使在最大大小读取时,缓冲区也有空间。
这里的问题是buffer
不是由recv()
以NULL结尾。 实际上, recv
只将原始套接字数据放入缓冲区。 如果它收到256字节的数据,那么之后的任何内容都可能是空字符(例如,因为它在您的服务器上)或者它可能是其他东西(就像它在您的客户端上)。 这是程序执行的工件,而不是你如何编程。
解决此问题的最简单,最快捷的方法:
- 分配大小为
MAXBUF + 1
buffer
。 +1将用于额外的NULL字符。 - 紧接在
printf
之前,在buffer[bytesRead]
添加一个空字符。
所以告诉所有人:
buffer = malloc((MAXBUF + 1) * sizeof(char)); // NEW while((byteRead = recv(ssock, buffer, MAXBUF, 0)) > 0) { if(byteRead <= 0) break; else { buffer[bytesRead] = '\0'; // NEW printf("%s", buffer); } }
是。
strlen()查找最近的NULL终止符,就像在传统的C字符串中一样。
recv()与null终止符无关,也不会添加一个。 因此,strlen调用是错误的,甚至可能会因未经授权的读取而导致程序崩溃。