Timeout bei connect(...) TCP/IP
-
Hallo,
in manchen Fällen bleibt meine Anwendung im connect hängen. Ich vermute, wenn der Server den Client nicht akzeptiert.
Deswegen jetzt meine Frage, gibt es eine Möglichkeit, für den connect einen Timeout zu setzen, nachdem er aus dem connect rausgeht, wenn der Verbindungsaufbau nicht akzeptiert wird?Hier ein Ausschnit aus meinem Code:
int sockfd, n; struct addrinfo hints, *res, *ressave; char *l_addrinfo; //to save info for this socket bzero(&hints, sizeof(struct addrinfo)); //init the struct hints.ai_family = PREFERRED_CONN; //tpye of connection hints.ai_socktype = SOCK_STREAM; //for tcp if ( (n = getaddrinfo(Host.c_str(), Port.c_str(), &hints, &res)) != 0) return -1; ressave = res; //save for freeaddrinfo do { sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (sockfd < 0) continue; /* ignore this one */ /** Hier geht er rein und bleibt hängen */ if (connect(sockfd, res->ai_addr, res->ai_addrlen) == 0) break; /* success */ if((n = close(sockfd)) != 0) /* ignore this one */ return -1; } while ( (res = res->ai_next) != NULL); ... ...
Danke und Grüße
dziubaErgänzung:
Also ich habe jetzt festgestellt, dass er nach etwa 3 Minuten aus dem connect rausgeht (mit errno = timeout). Gibt es eine Möglichkeit diesen Wert etwas kleiner zu setzen?
-
die einfachste moeglichkeit waere wohl mit alarm ein timeout zu setzen:
void connect_timeout(int signal) { cerr << "connect_timeout"; } if ( signal(SIGALRM, connect_timeout) == SIG_ERR ) cerr << "konnte alarm-handler nicht setzen..."; alarm(60); // rufe den alarm handler in 60 sekunden auf int c = connect(...); // connect liefert -1 und setzt errno auf EINTR, wenn es von einem // signal unterbrochen wird (der mit alarm gesetzte timer ist // abgelaufen) if ( c < 0 && errno == EINTR ) cerr <<"timeout"; else cout << "connect ok."; alarm(0); // alarm deaktivieren bei erfolgreichem connect
alternatv kannst du die sockets auf nicht blockierend setzen
und mit select auf einen timeout bzw erfolgreichen verbindungs-
aufbau warten.
das ist aber etwas komplizierter