从套接字读取缓冲区

发布于 2024-09-06 05:48:55 字数 551 浏览 6 评论 0原文

我正在用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

丑疤怪 2024-09-13 05:48:55

recv 不会在字符串末尾放置空终止符(而 printf %s 假设有一个)。

您必须使用byteRead 来确定字符串的长度。如果您想使用像 printf 这样的函数,请添加一个空终止符,但要确保您的缓冲区即使在最大大小读取时也有足够的空间。

recv does not place a null terminator at the end of the string (whilst printf %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 like printf, but ensure your buffer has the space for it even on a maximum-size read.

岁月无声 2024-09-13 05:48:55

这里的问题是 buffer 不是由 recv() 以 NULL 结尾的。事实上,recv 只是将原始套接字数据放入缓冲区。如果它接收到 256 字节的数据,则后面的任何内容都可能是空字符(例如,因为它在您的服务器上),也可能是其他字符(因为它在您的客户端上)。它是程序执行的产物,而不是您如何编程的产物。

解决此问题最简单、最快的方法是:

  1. 分配大小为 MAXBUF + 1buffer。 +1 将表示额外的 NULL 字符。
  2. 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);
    }
}

The problem here is that buffer is not NULL-terminated by recv(). 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:

  1. Allocate buffer with size MAXBUF + 1. The +1 will be for an extra NULL character.
  2. Immediately before the printf, add a null character at 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] = '\0';                      // NEW
        printf("%s", buffer);
    }
}
猛虎独行 2024-09-13 05:48:55

是的。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文