Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ UDP绑定EADDRINUSE与SO_REUSEADDR_C++_Sockets_Bind - Fatal编程技术网

C++ UDP绑定EADDRINUSE与SO_REUSEADDR

C++ UDP绑定EADDRINUSE与SO_REUSEADDR,c++,sockets,bind,C++,Sockets,Bind,我有一个多线程Linux服务器,它有许多同时连接(每个线程2个连接),在响应客户机时必须绑定到公共IP地址。绑定UDP套接字时,我不时会遇到EADDRINUSE错误,尽管我的日志表明套接字上次绑定到同一地址/端口并在套接字上调用shutdown()和close()是在30分钟之前 此外,我在这些UDP套接字(但不是自动绑定到本地地址/端口的套接字)上设置了SO_REUSEADDR、SO_REUSEPORT和IP_TRANSPARENT)。使用这些选项,即使有其他UDP套接字仍然绑定到本地地址上的

我有一个多线程Linux服务器,它有许多同时连接(每个线程2个连接),在响应客户机时必须绑定到公共IP地址。绑定UDP套接字时,我不时会遇到
EADDRINUSE
错误,尽管我的日志表明套接字上次绑定到同一地址/端口并在套接字上调用
shutdown()
close()
是在30分钟之前

此外,我在这些UDP套接字(但不是自动绑定到本地地址/端口的套接字)上设置了
SO_REUSEADDR
SO_REUSEPORT
IP_TRANSPARENT
)。使用这些选项,即使有其他UDP套接字仍然绑定到本地地址上的同一端口,绑定也不应该失败,因为
SO\u REUSEADDR
,但它显然确实发生了

我找不到这种行为的解释

int makeUDPSocket(sockaddr_in *bindTo)
{
    int sock;
    if(-1 == (sock = socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK, 0)))
    {
        log("Could not make client UDP socket! Exiting.");
        exit(18);
    }
    if(bindTo)
    {
        int enable = 1;
        if (-1 == setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&enable, sizeof(enable)))
        {
            log("Could not set SO_REUSEADDR on UDP socket; errno=" + std::to_string(errno));
            exit(2);
        }
        if (-1 == setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (const char*)&enable, sizeof(enable)))
        {
            log("Could not set SO_REUSEPORT on UDP socket; errno=" + std::to_string(errno));
            exit(2);
        }
        if(-1 == setsockopt(sock, SOL_IP, IP_TRANSPARENT, (const char*)&enable, sizeof(enable)))
        {
            log("Could not set IP_TRANSPARENT on UDP socket; errno=" + std::to_string(errno));
            exit(2);
        }
        if(-1 == bind(sock, (sockaddr*)bindTo, sizeof(sockaddr_in)))
        {
            log("Could not bind UDP socket. errno=" + std::to_string(errno) + ". Exiting.");
            exit(19);
        }
    }
    return sock;
}

void myfunc()
{
    int sock0 = makeUDPSocket(NULL);
    int sock1 = makeUDPSocket(&myPubAddr);
    doStuff(sock0, sock1);
    shutdown(sock0, SHUT_RDWR);
    close(sock0);
    shutdown(sock1, SHUT_RDWR);
    close(sock1);
}

这是一个很长的解释,但你会学到很多。如果您跳到SO_REUSEADDR的部分,您的问题很可能是您没有为自动绑定的局部变量启用它;实际上,我最近读过这个答案,但据我所知,
因此_REUSEADDR
不需要在以前绑定的套接字上启用,以便将新套接字绑定到不同的地址和相同的端口。我刚刚发现,在Windows上,您可以在同一端口上有多个UDP套接字,例如,一个套接字用于发送线程,另一个套接字用于接收线程。但在Linux中,任何给定端口号上只能有一个套接字,这迫使发送线程和接收线程共享同一个套接字,