2015-12-02 77 views
0

我们的软件在连接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)的 应用程序可以调用再次连接相同的套接字。

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

+0

关于这一行:'struct sockaddr_in addr = make_addr();'由多个字段组成的sockaddr_in不是原生C类型因此,分配将不起作用。也许一个指针可以工作,但是我会将调用并入memcpy() – user3629249

回答

1

你的代码总是错的。失败的connect()总是软管插座。你很幸运,它工作了这么久。

+0

请参阅编辑。根据MSDN,第一个代码片段应该正常工作。 –