【问题标题】:Do I need to offset a pointer when calling recv?调用recv时需要偏移指针吗?
【发布时间】:2021-12-14 05:14:30
【问题描述】:

在使用recv的时候,我一直都是这么干的:

int len = 1000;
int n = 0;

char buf[1000];
while(n < len) {
  n += recv(socket, buf + n, len - n, 0);
}

我的逻辑是,如果 recv 没有收到 len 字节的完整数据,我应该只收到其余字节 (len - n) 并且不应该覆盖已经收到的数据(所以我抵消了缓冲区的初学者到已接收内容的末尾)。每当我使用它时,这似乎都可以正常工作。

但是,我看到的大多数(如果不是全部)recv 示例只是执行以下操作:

int len = 1000;
int n = 0;

char buf[1000];
while(n < len) {
  n += recv(socket, buf, len, 0);
}

如果多次调用recv,这不会让您容易覆盖缓冲区的开头吗?

【问题讨论】:

  • "recv 的大多数(如果不是全部)示例'。除非这些示例只是试图在不使用数据的情况下使用数据,或者您将其脱离上下文,否则它看起来确实正如你所说的那样不正确。
  • 您的“偏移量”出现是因为您试图将来自多次调用 recv() 的数据存储到数组中,即您并不总是读取数组的第一个元素。您引用的示例都读取到缓冲区的第一个字符(因此第二次和后续调用 recv() 的数据会覆盖先前收到的数组元素)。这两种方法都是有效的,但在不同的情况下(即没有一些神奇的“总是这样做”的方法)。在所有情况下,都必须确保您的代码不会超出数组的末尾。

标签: c++ c pointers networking recv


【解决方案1】:

一切都很糟糕。 如果我们谈论的是 C,那么您至少需要 \0 的空间。只有在确定一切正常时才能将其删除。否则你无法测试它。所有这些东西意味着你不确定你是否可以一击完成,所以你可能会在那里说Transfer-Encoding: chunked。如果你不这样做

int btx;
....
char x[9001] = {0};
int b = 0;
int e = 0;
do
{
   b = recv(btx, x + e, 9000, 0);
   e = e + b;
}while(b != 0);

还有 C++

std::stringstream fbtc_b;
int btx;
....
int b = 0;
do
{
   char x[9000];
   b = recv(btx, x, 9000, 0);
   fbtc_b.write(x, b);
}while(b != 0);

【讨论】:

    【解决方案2】:

    您的两个示例都没有说明recv() 失败的可能性。您需要检查返回值是否有错误,例如:

    char buf[1000];
    int len = sizeof(buf);
    int n = 0, ret;
    
    while (n < len) {
      ret = recv(socket, buf + n, len - n, 0);
      if (ret <= 0) {
        // error handling...
        break;
      }
      n += ret;
    }
    

    当您预先知道需要读取多少字节并且可以预先分配一个足够大的缓冲区来容纳所有字节时,您的第一个示例非常适合。

    当您需要更动态地流式传输数据时,您的第二个示例非常适合使用,一次 1 个缓冲区。例如,也许数据正在保存到文件中。或者可能数据太大,无法放入这么小的缓冲区,需要分块处理。或者,数据可能会附加到另一个动态增长的缓冲区以供以后使用。这个用例有很多原因,例如:

    char buf[1000];
    int n;
    
    while (some condition) {
      n = recv(socket, buf, sizeof(buf), 0);
      if (n <= 0) {
        // error handling...
        break;
      }
      // use buf up to n bytes...
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-05-21
      • 1970-01-01
      • 2013-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多