0
有兩個套接字服務器,一個是不是始終打開的主服務器,另一個是備份服務器。切換回阻塞套接字後無法連接到套接字
我的程序將嘗試使用非阻塞連接來連接主服務器(以便可以應用超時值),如果失敗,它將使用阻塞連接來連接備份服務器。
然而第二連接函數將返回在大部分時間「無效參數」錯誤代碼:正如我在上面的代碼註釋
#define SERVER_URL "example.com"
#define SERVER_PORT_PRIMARY "1234"
#define SERVER_PORT_BACKUP "5678"
struct addrinfo *result = NULL;
struct addrinfo hints;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
if (getaddrinfo(SERVER_URL , SERVER_PORT_PRIMARY , &hints, &result) != 0) {
WSACleanup();
return;
}
SOCKET socketClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (socketClient == SOCKET_ERROR){
WSACleanup();
return;
}
//set the socket in non-blocking
unsigned long iMode = 1;
iResult = ioctlsocket(socketClient, FIONBIO, &iMode);
if (iResult != NO_ERROR){
closesocket(socketClient);
WSACleanup();
return;
}
if (connect(socketClient, result->ai_addr, (int)result->ai_addrlen) == SOCKET_ERROR){
if (WSAGetLastError() != WSAEWOULDBLOCK){
closesocket(socketClient);
WSACleanup();
return;
}
}
//switch it back to blocking socket
iMode = 0;
iResult = ioctlsocket(socketClient, FIONBIO, &iMode);
if (iResult != NO_ERROR){
closesocket(socketClient);
WSACleanup();
return;
}
fd_set Write, Err;
FD_ZERO(&Write);
FD_ZERO(&Err);
FD_SET(socketClient, &Write);
FD_SET(socketClient, &Err);
TIMEVAL Timeout;
Timeout.tv_sec = 10;
Timeout.tv_usec = 0;
select(0, NULL, &Write, &Err, &Timeout);
if (FD_ISSET(socketClient, &Write) == false){
//unable to connect to primary server within 10s, try to connect backup server
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
if (getaddrinfo(SERVER_URL , SERVER_PORT_BACKUP, &hints, &result) != 0) {
closesocket(socketClient);
WSACleanup();
return;
}
iResult = connect(socketClient, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR){
int a = WSAGetLastError(); ///<----Problem here, a == WSAEINVAL (Invalid argument)
closesocket(socketClient);
WSACleanup();
return;
}
}
,第二個「連接」的電話將在大部分時間和WSAGetLastError返回SOCKET_ERROR ()返回WSAEINVAL(無效參數)。
如果我刪除了非阻塞代碼,它將連接沒有錯誤。那麼我的代碼有什麼問題?