从套接字读取缓冲区
我正在用 c 编写简单的服务器/客户端,其中服务器临时存储来自客户端的消息并在客户端请求时检索它。
问题是当客户端从服务器接收消息时,缓冲区的行为有点奇怪。 我所做的只是读取从服务器接收的内容并将其打印在屏幕上,但不知何故缓冲区被覆盖超过
客户端
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在服务器端,它正确读取文件并将其发送到套接字。
I'm writing simple server/client in c, where server temporary stores message from client and retrieve it when client request it.
The problem is when client receives message from server, the buffer acts kinda weird.
All i did is read as much as receive from server and print it on the screen, but somehow buffer was overwrited more than maximum size of buffer
in client
while((byteRead = recv(ssock, buffer, MAXBUF, 0)) > 0)
{
if(byteRead <= 0)
break;
printf("%s", buffer);
}
where MAXBUF is 256. It keep contains some garbages so i examined the string size in buffer
and surprisingly
printf("%d READ vs %d buffer strlen \n", byteRead, strlen(buffer))
show me that byteRead is 256 but string length of buffer is 262.
Any idea??
P.s on server side, it reads file correctly and send it onto socket.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
recv
不会在字符串末尾放置空终止符(而printf
%s
假设有一个)。您必须使用
byteRead
来确定字符串的长度。如果您想使用像printf
这样的函数,请添加一个空终止符,但要确保您的缓冲区即使在最大大小读取时也有足够的空间。recv
does not place a null terminator at the end of the string (whilstprintf
%s
assumes there is one).You must use
byteRead
to determine the length of the string. Add a null terminator if you want to use a function likeprintf
, but ensure your buffer has the space for it even on a maximum-size read.这里的问题是
buffer
不是由recv()
以 NULL 结尾的。事实上,recv 只是将原始套接字数据放入缓冲区。如果它接收到 256 字节的数据,则后面的任何内容都可能是空字符(例如,因为它在您的服务器上),也可能是其他字符(因为它在您的客户端上)。它是程序执行的产物,而不是您如何编程的产物。解决此问题最简单、最快的方法是:
MAXBUF + 1
的buffer
。 +1 将表示额外的 NULL 字符。printf
之前,在buffer[bytesRead]
处添加一个空字符。总而言之:
The problem here is that
buffer
is not NULL-terminated byrecv()
. In fact,recv
only puts the raw socket data into the buffer. If it recieves 256 bytes of data, whatever comes after that might be null characters (e.g. as it is on your server) or it might be something else (as it is on your client). It's an artifact of program execution, not of how you programmed it.The easiest and fastest way to fix this:
buffer
with sizeMAXBUF + 1
. The +1 will be for an extra NULL character.printf
, add a null character atbuffer[bytesRead]
.So all-told:
是的。
strlen() 查找最近的 NULL 终止符,就像在传统的 C 字符串中一样。
recv() 与空终止符无关,并且不会加一。因此,strlen 调用是错误的,甚至可能因未经授权的读取而导致程序崩溃。
Yes.
strlen() looks for the nearest NULL terminator, as in a conventional C string.
recv() has nothing to do with null terminator and would not add one. So, the strlen call is wrong and may even crash your program by unauthorized read.