获取套接字中可读取的字节数

发布于 2025-01-01 21:30:01 字数 454 浏览 2 评论 0原文

这是我的场景。我有一个正在与服务器通信的 TCP 客户端。服务器和客户端都在本地计算机(Windows)上运行。

该对话框类似于:

  1. 客户端向服务器发送数据(请求)
  2. 客户端关闭套接字上的发送
  3. 客户端通过响应的读取调用
  4. 进行阻塞服务器接收数据、处理并发回响应(一次性,未中断)块)
  5. 服务器确实关闭套接字上的发送
  6. 客户端收到响应,并继续处理。

在步骤 3 中,我使用 recv() 调用来阻止并从套接字读取数据。此时,我想看看有多少字节的数据可用,以便我可以分配这么多内存。 按照设计,服务器已经发送了所有数据,并且没有更多数据可供该请求发送。 (参见上面的步骤 5)。

我尝试过使用 MSG_PEEK 选项的 recv() ,但这似乎没有给出可用的字节总数。

有办法找回吗?

提前致谢。

Here's my scenario. I have a TCP client that is talking to the server. Both the server and the client are running on local machine (Windows).

The dialog goes something like:

  1. Client sends data to the server (Request)
  2. Client does shutdown for send on the socket
  3. Client blocks via a read call for response
  4. Server receives the data, processes, and sends back a response (one shot, not broken into chunks)
  5. Server does shutdown for send on the socket
  6. Client receives the response, and continues processing.

At step 3, I am using recv() call to block and read data from the socket. At this point, I would like to peek to see how many bytes of data is available, so that I can allocate so much memory.
By design, it is known that the server has sent all the data, and there is no more data for this request to be sent. (See step 5 above).

I have tried recv() with MSG_PEEK option, but that does not seem to give the total number of bytes available.

Is there a way to retrieve it?

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(4

各自安好 2025-01-08 21:30:01

至少在 Windows 上,您可以将 ioctlsocket()FIONREAD 命令一起使用来确定可用于 recv() 的当前字节数不阻塞地阅读。不过,当您实际调用 recv() 时,可能已经到达更多字节。

正如 @LokiAstari 所说,您应该在循环中调用 recv() ,直到它返回 0 字节以指示套接字已关闭。您不需要知道有多少字节可用,只需每次传递一个固定长度的缓冲区,recv() 将返回实际读取了多少字节。将每个非零长度缓冲区读取附加到另一个根据需要增长的缓冲区中,直到收到所有数据,然后在准备好时处理第二个缓冲区。

On Windows at least, you can use ioctlsocket() with the FIONREAD command to determine the current number of bytes that are available for recv() to read without blocking. By the time you actually call recv(), more bytes may have arrived, though.

As @LokiAstari said, you should be calling recv() in a loop until it returns 0 bytes to indicate the socket has been closed. You do not need to know how many bytes are available, just pass a fixed-length buffer each time, and recv() will return how many bytes were actually read. Append each non-zero-length buffer read into another buffer that grows as needed until you have received all of the data, and then process that second buffer when ready.

可爱暴击 2025-01-08 21:30:01

使用 TCP 无法知道有多少字节。请记住,TCP 是一种“流”协议,流有一个开始,但直到连接关闭才结束。

您可以做的是将小块读入缓冲区,并在需要时扩大缓冲区。

Using TCP there is no way of knowing how much bytes there is. Remember that TCP is a "streaming" protocol, there is a start of the stream but no end until the connection has been closed.

What you can do is read small chunks into a buffer, and enlarge the buffer when needed.

薔薇婲 2025-01-08 21:30:01

在不预先分配或重新分配缓冲区的情况下执行此操作的一种方法是:(a) 发送发送方正在发送的字节数(例如,按照网络字节顺序作为四字节 int),(b)接收方接收这四个字节并分配接收缓冲区,然后 (c) 让接收方发送先前发送长度的实际数据。请注意,(c) 可能由发送方在没有从接收方收到有关 (a) 的反馈或答复的情况下发生。

我一直在尝试使用 fstat 来获取套接字上可用的数据量,但它似乎不可移植。在 Mac 系统上,它适用于我的应用程序。在 Linux 系统上则不然。

One way to do this, without pre-allocating or re-allocating buffers is to: (a) send the number of bytes the sender is sending (e.g., as a four byte int, in network byte order), (b) have the receiver receive those four bytes and allocate a receive buffer, and then (c) have the receiver send the actual data of the previously sent length. Note that (c) can occur by the sender without receiving feedback or a reply regarding (a) from the receiver.

I had been trying to use fstat to get the amount of data available on a socket, but it does not appear to be portable. On a Mac system, it works for my application. On a Linux system, it does not.

最近可好 2025-01-08 21:30:01

它部分取决于响应的大小,因为即使将其作为一个块发送,底层传输也可能将其分成多个块。例如,以太网的最大数据包大小为 1500 字节。虽然您一次性发送了所有数据,但您很可能会立即收到所有数据,但如果您使用 TCP,则不能保证,因为它是面向流的。如果您使用 UDP,您更有可能收到单个数据包形式的响应。

It partly depends on the size of the response because even if the send it as one chunk, the underlying transport may break it into chunks. For example, Ethernet has a maximum packet size of 1500 bytes. Although you send it all once, while it is likely that you will receive it all at once, it is not guaranteed if you are using TCP because it is stream oriented. You are much more likely to receive the response as a single packet if you use UDP.

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