C语言 从套接字读取缓冲区
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3074824/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
reading buffer from socket
提问by REALFREE
I'm writing simple server/client in c, where server temporary stores message from client and retrieve it when client request it.
我正在用 c 编写简单的服务器/客户端,其中服务器临时存储来自客户端的消息并在客户端请求时检索它。
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
其中 MAXBUF 是 256。它包含一些垃圾,所以我检查了缓冲区中的字符串大小,令人惊讶的是
printf("%d READ vs %d buffer strlen \n", byteRead, strlen(buffer))
show me that byteRead is 256 but string length of buffer is 262.
告诉我 byteRead 是 256,但缓冲区的字符串长度是 262。
Any idea??
任何的想法??
P.s on server side, it reads file correctly and send it onto socket.
Ps 在服务器端,它正确读取文件并将其发送到套接字。
回答by Artelius
recvdoes not place a null terminator at the end of the string (whilst printf%sassumes there is one).
recv不会在字符串末尾放置空终止符(同时printf%s假设有一个)。
You must use byteReadto determine the length of the string. Add a null terminator if you want to use a function like printf, but ensure your buffer has the space for it even on a maximum-size read.
您必须使用byteRead来确定字符串的长度。如果您想使用类似 的函数printf,请添加一个空终止符,但确保您的缓冲区即使在读取最大大小时也有足够的空间。
回答by Andres Jaan Tack
The problem here is that bufferis not NULL-terminated by recv(). In fact, recvonly 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.
这里的问题是它buffer不是由 NULL 终止的recv()。实际上,recv只是将原始套接字数据放入缓冲区。如果它收到 256 字节的数据,那么后面的可能是空字符(例如在您的服务器上),也可能是其他内容(在您的客户端上)。它是程序执行的产物,而不是您如何对其进行编程。
The easiest and fastest way to fix this:
解决这个问题的最简单和最快的方法:
- Allocate
bufferwith sizeMAXBUF + 1. The +1 will be for an extra NULL character. - Immediately before the
printf, add a null character atbuffer[bytesRead].
- 分配
buffer大小MAXBUF + 1。+1 将用于额外的 NULL 字符。 - 在 之前
printf,在 处添加一个空字符buffer[bytesRead]。
So all-told:
综上所述:
buffer = malloc((MAXBUF + 1) * sizeof(char)); // NEW
while((byteRead = recv(ssock, buffer, MAXBUF, 0)) > 0)
{
if(byteRead <= 0)
break;
else {
buffer[bytesRead] = '##代码##'; // NEW
printf("%s", buffer);
}
}
回答by Pavel Radzivilovsky
Yes.
是的。
strlen() looks for the nearest NULL terminator, as in a conventional C string.
strlen() 查找最近的 NULL 终止符,就像在传统的 C 字符串中一样。
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.
recv() 与空终止符无关,不会添加一个。因此, strlen 调用是错误的,甚至可能因未经授权的读取而导致程序崩溃。

