【问题标题】:pread and lseek not working on socket file descriptorpread 和 lseek 不适用于套接字文件描述符
【发布时间】:2012-08-12 11:12:05
【问题描述】:

这个问题是关于系统调用 pread 和 lseek 的。 我有一个套接字类型的文件描述符。每当从网络层读取数据包时,就会将数据添加到其中。我想知道文件描述符中定期存在的数据量是多少。

我尝试使用系统调用 pread 和 lseek,这样我只知道数据量而不是读取数据本身。但是,这两个调用都失败了,给出了非法搜索错误。套接字类型文件描述符上是否有任何其他系统调用,或者套接字 fd 不支持 pread 和 lseek? .

最好的 亚什

【问题讨论】:

    标签: sockets system-calls


    【解决方案1】:

    Linux manpages说sockets接口不支持seek操作:

    寻找或调用非零位置的pread(2) 或pwrite(2) 是 套接字不支持。

    您可以尝试发出 recv 并设置以下标志 (MSG_PEEK|MSG_DONTWAIT) 指定足够大小的缓冲区。

    此操作将从套接字的接收缓冲区复制数据,但不会将其弹出,即后续的recv/read 调用将读取所有相同的数据+更多数据可能会到达套接字,因此返回的字节数可能更大。

    缓冲区大小是一个非常棘手的问题 - 它应该大于套接字接收缓冲区,否则您的 recv 调用可能会返回您提供的缓冲区中的字节数,但套接字实际上还有一些。

    套接字接收缓冲区的大小可以通过getsockopt函数获得,选项名称为SO_RCVBUF

    顺便说一句,我认为更好的选择是实际读取数据并将其保存在缓冲区中的某个地方。当你读到足够的数据时,用它做一些动作。这似乎是一种比在不提取数据的情况下窥视套接字接收缓冲区更好、更常见的方法。

    【讨论】:

      【解决方案2】:

      您不能在套接字句柄上查找。 pread 有效地执行 lseek 然后是 read

      最好在循环中调用readrecv 并使用其中的内容。如需更广泛的答案,请参阅此SO question

      【讨论】:

        猜你喜欢
        • 2012-11-02
        • 1970-01-01
        • 2014-04-25
        • 2011-03-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多