【问题标题】:reading buffer from socket从套接字读取缓冲区
【发布时间】:2010-06-19 07:58:46
【问题描述】:

我正在用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。

有什么想法吗??

P.s 在服务器端,它正确读取文件并将其发送到套接字。

【问题讨论】:

    标签: c sockets buffer


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

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

      1. 使用大小MAXBUF + 1 分配buffer。 +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);
          }
      }
      

      【讨论】:

        【解决方案3】:

        是的。

        strlen() 查找最近的 NULL 终止符,就像在传统的 C 字符串中一样。

        recv() 与空终止符无关,不会加一。因此,strlen 调用是错误的,甚至可能会因未经授权的读取而导致程序崩溃。

        【讨论】:

        • 好的,我明白了。但是在服务器端,当客户端通过套接字向服务器发送消息时,它正确接收并且我没有添加空指针。即使我在发送给客户端之前添加了空指针,它仍然显示垃圾内容;
        • @REALFREE:当我们说空终止符时,我们指的是“nul”字符,而不是空指针。此外,在您的服务器案例中,它可能似乎因为好运而工作,但您做的事情不正确。
        猜你喜欢
        • 1970-01-01
        • 2012-09-25
        • 1970-01-01
        • 2021-07-31
        • 2016-04-22
        • 2020-09-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多