End Google Ads 201810 - BS.net 01 --> Dear all,

I have a question about Winsock.

My program is a TCP client which manipulates lots of socket connection concurrently.

One socket for each thread.

I use blocking mode at most of time, except creating a new connection to server.

I turn socket into non-blocking mode first, then use select() to check the socket before turning back.

I really don't want to waste time on uncertain blocking timeout and make sure the connection is established in the specific time.

Everything works well when most of server are reachable.

But here comes the question.

If the number of unreachable server increases(more than 5), the rest reachable server will fail on creating connection.

In this case, select() always return 0(means timeout) even though the server is originally reachable.

Here is the portion of my program to create connection:


Open(LPCTSTR addr, int port, DWORD dwTimeout)
{
_socket = 0;

SOCKET theSocket;
int nRet;
// Store information about the server
LPHOSTENT lpHostEntry;
lpHostEntry = gethostbyname(addr); // Specifying server by its name
if (lpHostEntry == NULL) {
return;
}

// Create the socket
theSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (theSocket == INVALID_SOCKET) {
return;
}

// Set socket to non-blocking mode
unsigned long ul = 1;
nRet = ioctlsocket(theSocket, FIONBIO, (unsigned long*)&ul);
if (nRet == SOCKET_ERROR) {
closesocket(theSocket);
return;
}

// Use SOCKADDR_IN to fill in address information
SOCKADDR_IN saServer;
saServer.sin_family = AF_INET;
saServer.sin_addr = *((LPIN_ADDR)*lpHostEntry->h_addr_list);
// ^ Address of the server being inserted into the address field
saServer.sin_port = htons(port);

// Connect to the server
nRet = connect(theSocket,
(LPSOCKADDR)&saServer, // Server address
sizeof(struct sockaddr)); // Length of address structure
if (nRet == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK) {
closesocket(theSocket);
return;
}

struct timeval timeout;
fd_set r;
FD_ZERO(&r);
FD_SET(theSocket, &r);
timeout.tv_sec = dwTimeout / 1000;
timeout.tv_usec = (dwTimeout % 1000) * 1000;

nRet = select(0, 0, &r, 0, &timeout);
if (nRet <span class="code-keyword">