There are two socket servers, one is the primary server which is not always on, and one is a backup server.
My program will try to connect the primary server using non-block connection (so that a timeout val can be applied), and if failed, it will connect the backup server using blocking connection.
However the second connect function will return "Invalid argument" error code in most timeļ¼
#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;
}
}
As I commented on the code above, the second "connect" call will return SOCKET_ERROR in most time and WSAGetLastError() returns WSAEINVAL (Invalid argument).
If I remove the non-blocking codes, it will connect with no error. So what's wrong with my code?