这个问题是关于系统调用 pread 和 lseek 的。我有一个套接字类型的文件描述符。每当从网络层读取数据包时,就会将数据添加到其中。我想知道文件描述符中定期存在的数据量是多少。
我尝试使用系统调用 pread 和 lseek,这样我只知道数据量而不是读取数据本身。但是,这两个调用都失败了,给出了非法搜索错误。套接字类型文件描述符上是否有任何其他系统调用,或者套接字 fd 不支持 pread 和 lseek?.
最佳雅什
这个问题是关于系统调用 pread 和 lseek 的。我有一个套接字类型的文件描述符。每当从网络层读取数据包时,就会将数据添加到其中。我想知道文件描述符中定期存在的数据量是多少。
我尝试使用系统调用 pread 和 lseek,这样我只知道数据量而不是读取数据本身。但是,这两个调用都失败了,给出了非法搜索错误。套接字类型文件描述符上是否有任何其他系统调用,或者套接字 fd 不支持 pread 和 lseek?.
最佳雅什
Linux 联机帮助页说套接字接口不支持查找操作:
套接字不支持查找或调用具有非零位置的 pread(2) 或 pwrite(2)。
您可以尝试recv
使用以下标志集(MSG_PEEK|MSG_DONTWAIT)
来指定足够大小的缓冲区。
此操作将从套接字的接收缓冲区复制数据,但不会将其弹出,即后续recv
/read
调用将读取所有相同的数据 + 更多数据可能会到达套接字,因此返回的字节数可能会更大。
缓冲区大小是一个非常棘手的问题 - 它应该大于套接字接收缓冲区,否则您的recv
调用可能会返回您提供的缓冲区中的字节数,但套接字实际上还有更多。
套接字接收缓冲区的大小可以通过getsockopt
带有选项名称的函数获得SO_RCVBUF
。
顺便说一句,我认为更好的选择是实际读取数据并将其保存在缓冲区中的某个地方。当你读到足够的数据时,用它做一些动作。这似乎是一种比在不提取数据的情况下窥视套接字接收缓冲区更好和更常见的方法。
您不能在套接字句柄上寻找。 pread
有效地执行 an lseek
then a read
。
最好调用read
或recv
循环并使用那里的内容。有关更广泛的答案,请参阅此SO question。