2010-11-12 3 views
7

im Client Ich habe einWarum erkennt dieser Server nicht, dass der Client den Socket für ihn geschlossen hat?

close(sockfd) 

wo sockfd die Buchse, die mit dem Server verbunden sind. Im Server ich dies habe:

if (sockfd.revents & POLLERR || 
    desc_set[i].revents & POLLHUP || desc_set[i].revents & POLLNVAL) { 
    close(sockfd.fd); 
    printf("Goodbye (connection closed)\n"); 
} 

Wo sockfd eine Struktur pollfd ist, und sockfd.fd ist der Dateideskriptor des Sockels des Kunden.

Wenn der Client den Socket schließt, wie ich dort aufstellte, scheint der Server es nicht mit dem zweiten Code zu erkennen (desc_set [i] .revents & POLLHUP, etc.).

Weiß jemand, was ist das Problem?

Antwort

9

Klingt, als ob Sie die Verbindung von der Clientseite zu half close geschafft haben. In diesem Zustand kann die Verbindung weiterhin Daten in einer Richtung senden, d. H. Sie arbeitet im Halbduplex-Modus. Dies ist beabsichtigt und würde Ihrem Server ermöglichen, auf das, was der Client gesendet hat, zu antworten. Normalerweise würde das bedeuten, eine Dateiübertragung abzuschließen und close() aufzurufen oder alle Aspekte der Abfrage zu beantworten. Im halbgeschlossenen Zustand können Sie noch sinnvoll Daten an die bereits close() genannte Seite senden. Auf Ihrem Server sehen Sie eof, wenn Sie versuchen, es zu lesen. close() bedeutet nur "Ich bin fertig Senden, zu beenden, was auch immer ich fragte".

POLLHUP, POLLERR und POLLNVAL überprüft nur die Ausgabeseite der lokalen Verbindung, die hier noch gültig ist. Es gibt eine POLLRDHUP, die eine GNU-Erweiterung ist, die das Schließen der anderen Seite erkennen sollte, aber die Tests, die du tust, überprüfen nur, ob es noch beschreibbar ist, nicht, wenn es noch lesbar ist.

Siehe auch this question, die über Java spricht, aber immer noch sehr verwandt.

+0

Entschuldigen Sie, dass Sie eine solche Frage stellen, aber wie kann ich diese GNU-Erweiterung in meinen Code integrieren? – dasen

+0

#define _GNU_SOURCE vor jedem # includes wird es tun. Der Server calling close() von seinem eigenen freien Willen, sobald es die Anfrage bedient wird, ist eine viel, viel schönere Art und Weise. – Flexo

+0

Ich habe diese GNU-Erweiterung verwendet, aber sie schließt immer noch nicht auf der Serverseite. – dasen

4

Ein Remote-Schließen oder Herunterfahren der Ausgabe ist weder ein Fehler noch ein Auflegen oder ein ungültiger Zustand. Es ist ein Leseereignis, so dass read() null zurückgibt. Behandeln Sie es einfach als Teil Ihrer normalen Leseverarbeitung.

BTW Ihre Testbedingung oben sollte sockfd.revents & lesen (POLLERR | POLLHUP | POLLNVAL).

+0

Richtig - eine anmutige 'close()' wird signalisiert, indem 'read()' 0 zurückgibt, also wird es durch 'POLLIN' signalisiert. – caf

Verwandte Themen