Einstellung time-out für die connect () - Funktion die tcp-socket-Programmierung in C bricht recv()
In meinem Programm, Wenn der server nicht erreichbar ist die connect-Funktion nutzen zu viel Zeit. Also versuche ich, genügend Zeit zu geben, sich zu verbinden, wählen Sie mit(). Das problem ist jetzt, dass wenn ich versuche, zum empfangen von Daten vom server mit recvfrom() ich erhielt den Fehler "EAGAIN". hier ist der code verwendet, um die Verbindung und empfangen von Daten vom server.
int sock;
struct sockaddr_in addr;
int connectWithServer
{
int status;
struct timeval timeout;
timeout.tv_sec = 10;
timeout.tv_usec = 0;
addr.sin_port = htons(port);
sock = socket (AF_INET,SOCK_STREAM,0);
inet_pton(AF_INET,serverIP,&addr.sin_addr);
fd_set set;
FD_ZERO(&set);
FD_SET(sock, &set);
fcntl(sock, F_SETFL, O_NONBLOCK);
if ( (status = connect(sock, (struct sockaddr*)&addr, sizeof(addr))) == -1)
{
if ( errno != EINPROGRESS )
return status;
}
status = select(sock+1, NULL, &set, NULL, &timeout);
return status;
}
long int receiveResponse (void *response , unsigned int length)
{
socklen_t sockLen = sizeof(struct sockaddr);
long int received = recvfrom(sock, response, length, 0,(struct sockaddr *)&addr, &sockLen);
printf("Received %ld bytes... err %d\n",received, errno);
return received;
}
recvfrom
undconnect
passt nicht. Erste ist für UDP-sockets, letzteres ist TCP im Zusammenhang- aber seine Arbeit gut, wenn es keine Zeit gibt, aus
- ja, es funktioniert, aber
from
parameter ist sinnlos, da Sie wissen, wer das peer. Egal, es war nur ein Vorschlag
Du musst angemeldet sein, um einen Kommentar abzugeben.
Korrektur. Einstellung der connect-timeout ist arbeiten. Was 'funktioniert nicht' ist die anschließende
recvfrom()
, und das ist, weil Sie Links den socket non-blocking-Modus und Sie wissen nicht, was Sie tun, mit den daraus resultierendenEAGAIN.
Also, entweder umgehen, indemselect()
zu sagen, wenn der socket bereit ist zu Lesen, sonst setzen Sie die Buchse wieder in blocking-Modus, der nach Beendigung der Verbindung.Den ersten erfolgreichen wählen Sie mittels der connect-operation abgeschlossen ist, aber nicht unbedingt, dass es gelingen, von verbinden Mann-Seite, die Sie überprüfen sollten
SO_ERROR
um sicherzustellen, dass es erfolgreich abgeschlossenAlso in Ihrem code, den Sie tun sollten, so etwas wie dieses:
Dann, wie bereits in der anderen Antwort, die Sie rufen soll, wählen Sie erneut vor dem schreiben oder Lesen aus dem socket.
SO_ERROR
nach der Auswahl für eine Verbindung.select()
gibt 0 zurück, dann bedeutet es, dass die socket-Zeitüberschreitung. Wenn Sie -1 zurück, dann ist es ein Fehler. Für >0, ist etwas Interessantes passiert auf den sockel. Ist es nicht Wert, um zu entscheiden, basiert auf, der? Warum brauchen wir, um zu überprüfen, SO_ERROR (Sind wir überprüfen für eine Ecke Fall, in dem der socket verbunden nur über timeout)?Erhalten Sie
EAGAIN
weil es keine Daten aus socket zu Lesen-Puffer und Ihre sockel gesetzt wurde alsnonblocking
. Da bist du nicht verbunden mit dem peer, ich bin nicht überrascht, es.Blick auf diese von
man recvfrom
:Einem anderen Fall könnte die folgende sein:
readfrom
oder nurread
) nur wenn Sie sicher sind, dass Sie etwas empfangen.Den sockel gesetzt werden sollte, um die blocking-Modus wieder vor dem Aufruf von recv().