套接字选项是否从侦听套接字inheritance到accept()?
假设传递给accept
的侦听套接字使用setsockopt
在其上设置了非默认选项。 这些选项(部分或全部?)是由接收连接的结果文件描述符inheritance的吗?
一些套接字选项在系统的较低级别处理。 虽然可以使用setsockopt设置大多数套接字选项。 参考: man setsockopt
因为你在任何Linux上都只提到POSIX,一般来说,作为你的范围。 accept()
(参考: man accept
)对于应inheritance哪些套接字选项以及从侦听fd拒绝哪些选项确实有一定的自由裁量权。
accept()不会修改作为参数传递给它的原始套接字。 accept()返回的新套接字不会从侦听套接字inheritance文件状态标志,如O_NONBLOCK,O_ASYNC。
因此,不应依赖于侦听套接字属性的inheritance或非inheritance(它必须在实现和许可证之间变化),应使用所需的套接字选项显式设置接受的套接字。(最佳实践)
man页面和机器中的实现代码将是accept()行为最相关的规范。在多个Linux变体中没有共同或标准规范。
不,他们不一定是inheritance的。 试试这个示例,它将初始套接字上的接收缓冲区大小( SO_RCVBUF
)设置为非默认值,然后将结果与inheritance的套接字进行比较。 运行此代码,侦听TCP端口12345,然后从任何其他程序连接到它。
#include #include #include #include #include #include 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
套接字选项是不适合其他地方的东西。 因此,期望不同的套接字选项具有不同的inheritance行为。 是否inheritance套接字选项取决于具体情况。
如果他们不是,那将是惊人的。
但是,一旦套接字接受了连接,它们中的一些可能变得无关紧要(例如,未完成的连接请求的数量)。