connect()失败后重用套接字与WSAETIMEDOUT?

时间:2015-12-02 11:16:51

标签: c windows sockets winapi windows-server-2012-r2

我们的软件在连接SIEMENS PLC时遇到问题。我们创建了一个套接字,并不断对其进行connect(),始终接收WSAETIMEDOUT。在完全相同的IP和端口上工作的Telnet到PLC。下面的伪代码:

// Does not work
SOCKET reconnect(char* ip) {
    SOCKET sock = socket(PF_INET,SOCK_STREAM,0);
    struct sockaddr_in addr = make_addr();
    int err;

    while(1) {
        err = connect(sock,(struct sockaddr FAR*) &addr,sizeof(addr));
        if( err==SOCKET_ERROR ) {
            log()  // WSAETIMEDOUT logged here
            continue;
        }
        return sock;
    }
}

更改代码以为每个connect()调用创建一个新套接字后,它似乎正常工作......

// Works
SOCKET reconnect(char* ip) {
    struct sockaddr_in addr = make_addr();
    int err;

    while(1) {
        SOCKET sock = socket(PF_INET,SOCK_STREAM,0);
        err = connect(sock,(struct sockaddr FAR*) &addr,sizeof(addr));
        if( err==SOCKET_ERROR ) {
            log()  // WSAETIMEDOUT logged here
            closesocket(sock);
            continue;
        }
        return sock;
    }
}

在多个版本的Windows中,第一个代码段已在生产中成功运行了大约20年。我怀疑它不遵循规范...是否有任何更改/更新Windows Server 2012 R2(客户正在运行)更改此行为?

修改

根据docs

  

如果返回的错误代码表明连接尝试失败   (即WSAECONNREFUSED,WSAENETUNREACH, WSAETIMEDOUT )   应用程序可以再次为同一个套接字调用connect。

......这使得这更令人费解。

1 个答案:

答案 0 :(得分:1)

你的代码总是错的。失败的connect()总是输入套接字。你很幸运它工作了这么久。