PDA

View Full Version : [c\socket] migliorare sistema di connessione...


mamo139
09-02-2010, 17:53
struct sockaddr_in sock; //la struttura per il socket
int s;
fd_set fds;
struct timeval timeout;
struct hostent ip; //la struttura per l'indirizzo
unsigned long cmd;

WORD wVersion;
WSADATA wsaData;
wVersion = MAKEWORD(2, 2);
WSAStartup(wVersion, &wsaData); //winsock startup

s = socket(AF_INET, SOCK_STREAM, 0);
cmd=1; // imposto modalitą socket non boccante (andrą gestita con select())
ioctlsocket( s, FIONBIO, &cmd);
// dati per Select
timeout.tv_sec = connect_timeout; // numero di secondi per il timeout
timeout.tv_usec = 0; // numero di microsecondi per il timeout
FD_ZERO(&fds);
FD_SET(s, &fds); // aggiungo s all'elenco dei socket gestiti da select

sock.sin_addr.S_un.S_un_b.s_b1=ip1; // indico l'indirizzo IP
sock.sin_addr.S_un.S_un_b.s_b2=ip2;
sock.sin_addr.S_un.S_un_b.s_b3=ip3;
sock.sin_addr.S_un.S_un_b.s_b4=ip4;
sock.sin_port = htons(ipport); //porta

if(ip1==127 && ip2==0 && ip3==0 && ip4==1){ //se vogliamo utilizzare il nostro ip
ip = *(gethostbyname(host)); // indico l'indirizzo
memcpy(&sock.sin_addr, ip.h_addr, ip.h_length); //copia l'indirizzo nella struttura socket
}

sock.sin_family = AF_INET;


connect(s, (struct sockaddr *)&sock, sizeof(sock)); //ci connettiamo
if (select(s+1, 0, &fds, 0, &timeout)>0){ //riusciamo a stabilire la connessione


cmd=0;//ripristino socket bloccante
ioctlsocket( s, FIONBIO, &cmd);


questo č il modo con cui mi connetto in un mio programma.
ha un problema: č lento, ci mette sempre almeno il tempo impostato nella variabile connect_timeout a ricevere i dati dalla connessione.
A me piacerebbe fare una connessione che se il server al quale mi connetto č attivo io gli mando subito e lui risponde subito, se il server non c'č quando č trascorso il tempo connect_timeout proseguiamo con il programma.

Come posso migliorare quindi questo codice che funziona ma č troppo lento??
Grazie mille

fero86
09-02-2010, 18:04
ma perché fai la connessione in modalitį non bloccante e poi tutto il resto in modalitį bloccante? :mbe:
io ti consiglierei di usare la modalitį bloccante per tutto, é piu facile da usare; quella non bloccante la userei solo per necessitį specifiche.

PS: per vedere se un indirizzo é l'indirizzo di loopback usa la costante INADDR_LOOPBACK

mamo139
09-02-2010, 18:09
ma perché fai la connessione in modalitį non bloccante e poi tutto il resto in modalitį bloccante? :mbe:
io ti consiglierei di usare la modalitį bloccante per tutto, é piu facile da usare; quella non bloccante la userei solo per necessitį specifiche.

PS: per vedere se un indirizzo é l'indirizzo di loopback usa la costante INADDR_LOOPBACK

perche č l'unico modo che mi č venuto in mente per impostare un tempo di connessione. Infatti utilizzo questa connessione per collegarmi a dei proxy, ma non so se questi sono up o down quando mi connetto e purtroppo se sono down o non funzionano correttamente la funzione connect() puo rimanere bloccata per diverso tempo in modalitą bloccante.
Per questo avevo pensato a fare la connect in modo non bloccante...
tu come risolveresti il problema??

scusa non ho capito bene a cosa mi servirebbe INADDR_LOOPBACK

fero86
09-02-2010, 18:34
perche č l'unico modo che mi č venuto in mente per impostare un tempo di connessione. Infatti utilizzo questa connessione per collegarmi a dei proxy, ma non so se questi sono up o down quando mi connetto e purtroppo se sono down o non funzionano correttamente la funzione connect() puo rimanere bloccata per diverso tempo in modalitą bloccante.
Per questo avevo pensato a fare la connect in modo non bloccante...
tu come risolveresti il problema?? ah, capito; in effetti provando a guardare qua: http://www.linuxmanpages.com/man7/tcp.7.php
mi sembra che non ci sia nulla di specifico.


scusa non ho capito bene a cosa mi servirebbe INADDR_LOOPBACK nel tuo codice ip é una struct di tipo hostent, quindi potresti fare:
if (*(struct in_addr*)ip.h_addr != INADDR_LOOPBACK) {
// altro indirizzo
} else {
// 127.0.0.1
}
INADDR_LOOPBACK puó essere considerata un'espressione di tipo struct in_addr.