c++ - 检查文件描述符中可用缓冲区字符的数量

标签 c++ linux sockets posix

如何检查套接字文件描述符的缓冲区中有多少可用字符?

我想推迟从套接字读取字节,直到至少有 8 个字节可用(对于以下消息的长度)。我正在使用 select() 等待传入数据。当调用套接字的读取处理程序时,如果可用字节少于 8 个字节,我希望它只返回而不读取。

套接字是否可读,但只能读取少于 8 个字节?

是否有一个 Linux 系统调用可以检索可从套接字读取的字节数,而无需实际读取它们?

最佳答案

您可以使用ioctl()使用 FIONREAD (SIOCINQ) 请求。

来自tcp(7)联机帮助页:

The following ioctl(2) calls return information in value. The correct syntax is:

int value;
error = ioctl(tcp_socket, ioctl_type, &value);

ioctl_type is one of the following:

SIOCINQ
Returns the amount of queued unread data in the receive buffer. The socket must not be in LISTEN state, otherwise an error (EINVAL) is returned. SIOCINQ is defined in <linux/sockios.h>. Alternatively, you can use the synonymous FIONREAD, defined in <sys/ioctl.h>.

...

来自udp(7)联机帮助页:

These ioctls can be accessed using ioctl(2). The correct syntax is:

int value;
error = ioctl(udp_socket, ioctl_type, &value);

FIONREAD (SIOCINQ)
Gets a pointer to an integer as argument. Returns the size of the next pending datagram in the integer in bytes, or 0 when no datagram is pending. Warning: Using FIONREAD, it is impossible to distinguish the case where no datagram is pending from the case where the next pending datagram contains zero bytes of data. It is safer to use select(2), poll(2), or epoll(7) to distinguish these cases.

...

只要套接字的接收缓冲区至少包含 TCP 中的 1 个字节或 UDP 中的 1 个数据报,套接字就会处于可读状态。或者,在 TCP 的情况下,如果连接已被对等方正常关闭(收到 FIN 数据包),在这种情况下,后续读取将报告 0 字节。

关于c++ - 检查文件描述符中可用缓冲区字符的数量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63277370/

相关文章:

linux - 使用 Bash 删除具有特定模式的行

linux - 在 unix 中搜索模式为 [A-Z] 的文件

c++ - boost::asio::tcp 套接字上的双向通信

python - 'cv::Point2f&' 类型的非常量引用的初始化无效

c++ - 使用命令行参数控制程序中的打印输出

c++ - 如何比较程序中的两个日期?

C、Unix 域套接字、辅助数据和 GCC;使用 CMSG_DATA 宏

c++ - 如何添加 2 个四位十六进制来生成 ASCII 字符字节

linux - 当输出文件有字符串时发送电子邮件的 Netcat 脚本

c - accept() 返回的新连接套接字是否总是绑定(bind)到与监听套接字相同的端口?