这似乎是一个愚蠢的问题,但却使我发疯。我正在从事网络编程任务,编写的代码的一部分是调用带有缓冲区,缓冲区长度和为标志指定的零的socket recv()函数。 recv()调用返回的值为零,手册页显示返回值为零表示“流套接字对等体已执行有序关闭”。
问题在于recv()调用确实确实接收了数据,并且确实更新了我的缓冲区。我知道,因为我可以使用printf将其打印出来,并且期望在recv()调用期间接收到的数据显示在printf输出中。但问题在于,由于recv()返回零,所以我实际上并不知道实际上有多少数据放入了缓冲区。我在缓冲区上做一个memset,然后在使用它之前将其零清零,所以我猜我以后可以在缓冲区上进行strlen()调用,但这似乎很容易。这是我应该做的吗?
另一件事是该套接字仍处于打开状态,因为然后在第一次recv()调用后不久,我在while循环中对套接字进行了循环,并继续接收更多数据。我正在使用的缓冲区的大小是一个char buffer [4096]数组。任何见识将不胜感激。
最佳答案
那根本不可能。 recv()
可以:
这就对了。
recv()
无法接收某些数据,但返回0。是一个或另一个。唯一的可能发生的方式是,如果第一个
recv()
返回0是因为请求了0个字节,而不是因为发生了关闭。如果发生真正的关机,则所有后续读取将不再接收任何数据。他们不能。通过接收FIN
数据包可发出正常关闭信号,这意味着将不再发送任何数据。一旦发送了FIN
,发送方的套接字堆栈将不允许再发送任何数据。这是TCP工作方式的一部分。您的代码中显然有一个错误(未显示)。有时,您必须将缓冲区大小0传递给
recv()
,使其返回0。这是给定非零缓冲区大小时,后续读取仍可能接收更多数据的唯一方法。关于c - 我如何知道套接字recv()函数返回值0时收到了多少数据?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39673399/