这似乎是一个愚蠢的问题,但却使我发疯。我正在从事网络编程任务,编写的代码的一部分是调用带有缓冲区,缓冲区长度和为标志指定的零的socket recv()函数。 recv()调用返回的值为零,手册页显示返回值为零表示“流套接字对等体已执行有序关闭”。

问题在于recv()调用确实确实接收了数据,并且确实更新了我的缓冲区。我知道,因为我可以使用printf将其打印出来,并且期望在recv()调用期间接收到的数据显示在printf输出中。但问题在于,由于recv()返回零,所以我实际上并不知道实际上有多少数据放入了缓冲区。我在缓冲区上做一个memset,然后在使用它之前将其零清零,所以我猜我以后可以在缓冲区上进行strlen()调用,但这似乎很容易。这是我应该做的吗?

另一件事是该套接字仍处于打开状态,因为然后在第一次recv()调用后不久,我在while循环中对套接字进行了循环,并继续接收更多数据。我正在使用的缓冲区的大小是一个char buffer [4096]数组。任何见识将不胜感激。

最佳答案



那根本不可能。 recv()可以:

  • 接收1个或更多字节,并返回一个正值,指定接收了多少个字节。
  • 正常关闭时
  • 返回0,但未接收到数据。
  • 如果请求了0个字节,则
  • 返回0。
  • 在错误时返回-1。

  • 这就对了。 recv()无法接收某些数据,但返回0。是一个或另一个。



    唯一的可能发生的方式是,如果第一个recv()返回0是因为请求了0个字节,而不是因为发生了关闭。如果发生真正的关机,则所有后续读取将不再接收任何数据。他们不能。通过接收FIN数据包可发出正常关闭信号,这意味着将不再发送任何数据。一旦发送了FIN,发送方的套接字堆栈将不允许再发送任何数据。这是TCP工作方式的一部分。

    您的代码中显然有一个错误(未显示)。有时,您必须将缓冲区大小0传递给recv(),使其返回0。这是给定非零缓冲区大小时,后续读取仍可能接收更多数据的唯一方法。

    关于c - 我如何知道套接字recv()函数返回值0时收到了多少数据?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39673399/

    10-12 16:09
    查看更多