以下是我的测试夹具的本质-
SetUp()
{
g_listen_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
/* localhost is the server */
bind(g_listen_sock, (struct sockaddr *)&server_addr, sizeof(server_addr));
listen(g_listen_sock, max_connections);
}
testcase()
{
hdl = accept(g_listen_sock, NULL, NULL);
-- send()/recv() data on the socket --
}
TearDown()
{
shutdown(g_listen_sock, SHUT_RDWR);
close(g_listen_sock);
g_listen_sock = INVALID_SOCKET;
}
在应用程序的正常使用中,侦听套接字在应用程序的生命周期内仅绑定一次,但是测试设置会反复打开和关闭侦听套接字。测试用例的第一次迭代工作正常,但随后的迭代在通过errno == 98
即EADDRINUSE的bind()调用失败。
如何避免这种情况? 理想情况下,该解决方案不需要我拥有单独的代码测试版本,例如在测试时使用SO_REUSEADDR。
P.S。 -相同的代码在Windows上运行良好,bind()失败在Linux上发生。
答案 0 :(得分:9)
您要解决的是网络TCP层的内置功能。 linux内核不允许您重新绑定该套接字,因为关闭的套接字将处于TIME_WAIT状态。除了使用SO_REUSEADDR
(如您已经指出的那样),或者对每个测试使用不同的端口,这听起来都不是您想要执行的,您无可避免。
不幸的是,TCP并非设计为连续多次关闭和打开相同的IP /端口以进行测试,因此,如果仍要进行这种测试,则必须选择毒药。
另请参阅this answer,以更深入地探讨您的问题。