【问题标题】:Why is "setsockopt()" needed if "fcntl()" also manipulates file descriptors?如果“fcntl()”也操纵文件描述符,为什么需要“setsockopt()”?
【发布时间】:2021-12-30 18:37:49
【问题描述】:

在 C 中进行套接字编程时,我注意到有时 fcntl() 用于操作套接字行为,而其他时候则使用 setsockopt()

例如,fcntl() 用于制作socket non-blocking,但setsockopt() 用于更改timeout time when sending/receiving data from a socket

对于为什么需要这两个功能有任何背景/直观的推理吗?

【问题讨论】:

  • fcntl() 操作文件描述符,而setsockopt() 操作套接字描述符。在 Unix 风格的操作系统下,这两种类型的描述符大部分是可互换的,但在其他操作系统(阅读:Windows)下,文件描述符和套接字描述符是不同/不兼容的对象类型,因此需要不同的 API 来处理。 (你可以问一个类似的问题并得到类似的推理:send()/recv() vs read()/write

标签: c sockets posix nonblocking


【解决方案1】:

套接字不是唯一可以非阻塞的文件描述符类型。理论上,您可以将任何文件描述符标记为非阻塞(通过在 open() 文件时指定 O_NONBLOCK)但该设置可能会被忽略(对于不实现非阻塞模式的常规文件或特殊文件)。所以非阻塞标志是通用文件接口的一部分。

相比之下,套接字超时仅适用于套接字。只能使用特定于套接字的接口设置它们这一事实清楚地表明了这一点。 (终端设备有两个读取超时属性——VTIME 和 VMIN——它们之间的关系很模糊,但语义却大不相同。它们是通过termios 接口设置的。)

很少有普遍适用的属性可以用fcntl 操作。有许多属性特定于某些类型的文件,并且可以使用各种特定的接口进行操作。

【讨论】:

    猜你喜欢
    • 2013-05-09
    • 1970-01-01
    • 2014-04-07
    • 2015-06-08
    • 1970-01-01
    • 2023-03-04
    • 2017-05-12
    • 2017-04-13
    • 1970-01-01
    相关资源
    最近更新 更多