假设传递给
accept
的监听套接字在 setsockopt
中设置了非默认选项。这些选项(部分或全部?)是否会被接受连接的结果文件描述符继承?accept
的监听套接字在 setsockopt
中设置了非默认选项。这些选项(部分或全部?)是否会被接受连接的结果文件描述符继承?其中一些套接字选项在系统的较低层处理。虽然大多数套接字选项都可使用setsockopt进行设置。参考文献:man setsockopt
由于您提到了在任何Linux上一般只使用POSIX,因此accept()
(参考:man accept
)确实有一定的自主权,可以继承哪些套接字选项并拒绝从侦听fd继承哪些选项。
accept()不会修改作为其参数传递的原始套接字。 accept()返回的新套接字不会继承文件状态标志,例如O_NONBLOCK、O_ASYNC等来自监听套接字的标志。
因此,与其依赖于继承或不继承侦听套接字属性(这将因实现和许可证而异),不如显式设置所需的套接字选项以供接受的套接字使用。(最佳实践)
man页面和机器中的实现代码是accept()行为最相关的规范。在多个Linux变体之间不存在通用或标准规范。
O_
选项与setsockopt
选项不同。 - R.. GitHub STOP HELPING ICEO_
选项可以通过fcntl()系统调用应用于套接字fd。然后可以将套接字传递给accept()。参考:man socket
。 - askmish不,它们并不一定是继承的。尝试这个示例,它将接收缓冲区大小(SO_RCVBUF
)设置为非默认值,并将结果与继承的套接字进行比较。运行此代码,它会监听TCP端口12345,然后从任何其他程序连接到它。
#include <errno.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
void die(const char *f)
{
printf("%s: %s\n", f, strerror(errno));
exit(1);
}
int main(void)
{
int s = socket(AF_INET, SOCK_STREAM, 0);
if(s < 0)
die("socket");
int rcvbuf;
socklen_t optlen = sizeof(rcvbuf);
if(getsockopt(s, SOL_SOCKET, SO_RCVBUF, &rcvbuf, &optlen) < 0)
die("getsockopt (1)");
printf("initial rcvbuf: %d\n", rcvbuf);
rcvbuf *= 2;
if(setsockopt(s, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)) < 0)
die("setsockopt");
printf("set rcvbuf to %d\n", rcvbuf);
struct sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(12345);
sin.sin_addr.s_addr = INADDR_ANY;
if(bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0)
die("bind");
if(listen(s, 10) < 0)
die("listen");
struct sockaddr_in client_addr;
socklen_t addr_len = sizeof(client_addr);
int s2 = accept(s, (struct sockaddr *)&client_addr, &addr_len);
if(s2 < 0)
die("accept");
printf("accepted connection\n");
optlen = sizeof(rcvbuf);
if(getsockopt(s2, SOL_SOCKET, SO_RCVBUF, &rcvbuf, &optlen) < 0)
die("getsockopt (2)");
printf("new rcvbuf: %d\n", rcvbuf);
return 0;
}
一台运行Linux 3.0.0-21-generic操作系统的机器所得到的结果:
initial rcvbuf: 87380
set rcvbuf to 174760
accepted connection
new rcvbuf: 262142
setsockopt
之后立即执行另一个getsockopt
,令人惊讶的是,它返回了一个不同的值,然后被继承到了新的套接字中。然而,仅仅因为在这种情况下它被继承了,并不意味着所有选项都必然被继承,或者该行为可以被依赖。 - Adam Rosenfield套接字选项是放置那些不适合其他地方的东西的地方。因此,不同的套接字选项具有不同的继承行为是可以预期的。是否继承套接字选项取决于具体情况。