如果 "fcntl()" 也操纵文件描述符,为什么还需要 "setsockopt()"?

Why is "setsockopt()" needed if "fcntl()" also manipulates file descriptors?

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

例如,fcntl()用于制作socket non-blocking, but setsockopt() is used to change the timeout time when sending/receiving data from a socket

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

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

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

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