我们的软件在连接SIEMENS PLC时出现问题。我们创建了一个套接字并不断在其上连接(),并始终接收WSAETIMEDOUT。在完全相同的IP和端口上工作,通过Telnet到PLC。下面的伪代码:connect()在WSAETIMEDOUT失败后重新使用套接字?
// 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()调用创建一个新的socket之后,它似乎工作...
// 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;
}
}
的第一个片段已在生产中成功运行〜20年,跨多个版本的Windows。我怀疑它不符合规范,但是...是否有任何更改/更新Windows Server 2012 R2(这是客户正在运行的)改变这种行为?
编辑
按照docs,
如果返回错误代码表示连接尝试失败 (即WSAECONNREFUSED,WSAENETUNREACH,WSAETIMEDOUT)的 应用程序可以调用再次连接相同的套接字。
......这使得这更令人费解。
关于这一行:'struct sockaddr_in addr = make_addr();'由多个字段组成的sockaddr_in不是原生C类型因此,分配将不起作用。也许一个指针可以工作,但是我会将调用并入memcpy() – user3629249