C 尝试重新绑定已关闭的侦听套接字失败(EADDRINUSE)?
下面是我的测试夹具的要点-C 尝试重新绑定已关闭的侦听套接字失败(EADDRINUSE)?,c,linux,sockets,C,Linux,Sockets,下面是我的测试夹具的要点- 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); }
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;
}
在应用程序的正常使用中,侦听套接字在应用程序的生命周期内仅绑定一次,但是测试设置会重复打开和关闭侦听套接字。testcase的第一次迭代工作正常,但后续迭代在bind()调用时失败,即使用errno==98
EADDRINUSE
我如何避免这种情况理想情况下,解决方案不需要我有单独的代码测试版本,例如在测试时使用SO\U REUSEADDR。
另外,同样的代码在Windows上运行良好,bind()故障发生在Linux上。您试图绕过的是TCP网络层的内置功能。linux内核将不允许您重新绑定该套接字,因为关闭的套接字将处于时间等待状态。除了使用
SO_REUSEADDR
(正如您已经指出的),或者通过为每个测试使用不同的端口(听起来您也不想这样做),您没有什么办法可以避免这种情况
不幸的是,TCP并不是设计用来连续多次关闭和打开同一IP/端口进行测试的,因此如果您仍然想进行此类测试,您必须选择您的毒药
另请参阅,以获得对您的问题的更深入的探索 为什么在Windows中重复重新打开时会有不同?老实说,我不知道为什么会发生这种情况。当我在windows上进行套接字编程时,我通常会遇到与您相同的问题。不过,Windows和Linux是不同的操作系统,问题在于操作系统级别(可以这么说)。因此,这只是操作系统之间TCP实现不同的结果。在Windows注册表中更改等待时间延迟相当简单。但是,最好在专用的测试盒上进行测试,因为这是一个机器范围的设置。可能会重复和
,但是测试设置会重复打开和关闭监听插座。
不要这样做。相反,停止select()
ing侦听套接字,并停止accept()
ing传入连接。客户端将不得不等待一段时间(而不是重新设置连接)