我使用一个简单的googletest来获取套接字是否被设置为监听。套接字级别SO_ACCEPTCONN
上有一个选项,它显示套接字有一个listen()调用。
TEST(SocketTestSuite, check_listen) {
int sockfd = socket(AF_INET6, SOCK_STREAM, 0);
ASSERT_NE(sockfd, INVALID_SOCKET);
int so_option = 987654321;
socklen_t optlen{sizeof(so_option)};
int ret = getsockopt(sockfd, SOL_SOCKET, SO_ACCEPTCONN, &so_option, &optlen);
if (ret != 0) {
perror("Error getsockopt");
}
EXPECT_EQ(so_option, 0);
}
在Linux上,我得到了预期的结果:套接字未设置为侦听。
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from SocketTestSuite
[ RUN ] SocketTestSuite.check_listen
[ OK ] SocketTestSuite.check_listen (0 ms)
[----------] 1 test from SocketTestSuite (0 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (0 ms total)
[ PASSED ] 1 test.
在MacOS上,我得到:
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from SocketTestSuite
[ RUN ] SocketTestSuite.check_listen
Error getsockopt: Protocol not available
/Users/runner/work/client-server-tcp/client-server-tcp/test_client-server-tcp.cpp:165: Failure
Expected equality of these values:
so_option
Which is: 987654321
0
[ FAILED ] SocketTestSuite.check_listen (0 ms)
[----------] 1 test from SocketTestSuite (0 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (0 ms total)
[ PASSED ] 0 tests.
[ FAILED ] 1 test, listed below:
[ FAILED ] SocketTestSuite.check_listen
为什么会抱怨**“Protocol not available”**?什么协议?SO_ACCEPTCONN
是一个socket选项。不管怎么样,如果我使用TCP协议6:
int ret = getsockopt(sockfd, 6, SO_ACCEPTCONN, &so_option, &optlen);
我得到这个结果:
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from SocketTestSuite
[ RUN ] SocketTestSuite.check_listen
/Users/runner/work/client-server-tcp/client-server-tcp/test_client-server-tcp.cpp:164: Failure
Expected equality of these values:
so_option
Which is: 1024
0
[ FAILED ] SocketTestSuite.check_listen (0 ms)
[----------] 1 test from SocketTestSuite (0 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (0 ms total)
[ PASSED ] 0 tests.
[ FAILED ] 1 test, listed below:
[ FAILED ] SocketTestSuite.check_listen
MacOS现在对它的协议很满意,但它显示so_option = 1024
为trueas option!= 0。这是错误的。套接字没有设置为侦听。1024是0x 400,看起来像一个位设置选项,但我不知道为什么会给出这个选项。
这是怎么回事?为什么MacOS不能像Linux那样正常工作?
参考文献:
Mac OS X standard socket.h file
getsockopt() — Get the options associated with a socket
1条答案
按热度按时间mfpqipee1#
“Protocol not available”是
ENOPROTOOPT
的文本错误消息,当您尝试使用“unknown at the level indicated”的(get|set)sockopt()
选项时,errno
会报告此消息。换句话说,这意味着MacOS告诉你它不识别
SOL_SOCKET
级别的SO_ACCEPTCONN
选项。这是有道理的,因为根据Apple的OSX文档(并通过各种在线来源确认),getsockopt()
和setsockopt()
不支持SO_ACCEPTCONN
选项。SO_ACCEPTCONN
的数值为2
。通过将级别设置为6
(IPPROTO_TCP
),您将向getsockopt()
请求TCP选项2,即TCP_MAXSEG
(传出TCP数据包的最大段大小)。因此,您需要相应地调整您的测试:
AFAIK,没有其他的
getsockopt()
选项可以替代SO_ACCEPTCONN
。我知道的测试套接字是否在监听的唯一方法是使用accept()
,如果在没有监听的套接字上调用EINVAL
,它将失败。