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.

But here comes the question.

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

select() will 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 <= 0 ) {
closesocket(theSocket);
return;
}

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

_socket = theSocket;
}

Is there anything wrong in this code?

Or I just shouldn't use select() in multithread?



Best regards,

Luder