E questo è lo schema per il client, anzi, è una funzione che mi sono scritto per facilitare la connessione al server, cerca di impostare la connessione in modo non blocking, se non riesce la lascia impostata in modo blocking, in certe circostanze è meglio avere socket bloccanti, comunque...
codice:
SOCKET Connect(char * host, short port, int timeout)
{
unsigned long ulAddress;
int p;
HOSTENT hostent;
HOSTENT * h;
SOCKET s;
TIMEVAL tv;
fd_set writefds;
struct sockaddr_in s_in;
if(host == NULL)
{
return INVALID_SOCKET;
}
//OPENS SOCKET
s = socket(AF_INET, SOCK_STREAM, 0);
if (s == INVALID_SOCKET )
{
return s;
}
//non blocking mode
p = 1;
p = ioctlsocket(s, FIONBIO ,(ULONG*)&p);
//prova a usare formato xxx.xxx.xxx.xxx ...
ulAddress = inet_addr(host);
if(ulAddress == INADDR_NONE)
{ //... errore: bisogna risolvere hostname
h = gethostbyname(host);
if (h==NULL)
{
closesocket(s);
return INVALID_SOCKET;
}
}
else
{ //... ok: gethostbyaddr
h = gethostbyaddr((char*) &ulAddress, sizeof(ulAddress), AF_INET);
if (h==NULL)
{
closesocket(s);
return INVALID_SOCKET;
}
}
memcpy(&hostent, h, sizeof(hostent));
memset(&s_in, 0, sizeof(s_in));
memcpy(&s_in.sin_addr,hostent.h_addr,hostent.h_length);
s_in.sin_family = AF_INET;
s_in.sin_port = htons(port);
//PROVA A CONNETTERSI
if (connect(s, (struct sockaddr*)&s_in, sizeof(s_in)) == SOCKET_ERROR)
{
if (errno == EWOULDBLOCK)
//non ancora connesso (potrebbe ancora riuscire)
{
FD_ZERO(&writefds);
FD_SET(s, &writefds);
tv.tv_sec = timeout;
tv.tv_usec = 0;
p = select(0, NULL, &writefds, NULL, &tv);
//aspetta a vedere se riesce a collegarsi prima del timeout
if(p == 0) //failed
{
tv.tv_sec = 0;
p = select(0, NULL, NULL, &writefds, &tv);
if(p == SOCKET_ERROR)//failed
{
closesocket (s);
return INVALID_SOCKET;
}
else if(p==0)//failed ( timeout)
{
closesocket(s);
return INVALID_SOCKET;
}
}
}
else //connection failed
{
closesocket(s);
return INVALID_SOCKET;
}
}
return s;
}