我们的软件在连接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。
......这使得这更令人费解。
答案 0 :(得分:1)
你的代码总是错的。失败的connect()
总是输入套接字。你很幸运它工作了这么久。