2010-06-22 10 views
17

Rückkehr ich eine Anwendung habe, die eine Socket-Verbindung auf eine Portnummer 5005 mit einem anderen Gerät (Hardware-Gerät mit einem Webserver) aufgebaut. Jetztrecv() Funktion Socket Daten mit Länge 0

wenn mein Hardwaregerät trennt dann verlieren i Verbindung mit dem Gerät.

  1. Bedeutet dies, dass die Buchse i bis jetzt ungültig wird verwendet wurde.

  2. Erhalte ich irgendeine spezielle Nachricht wie Nullzeichen oder etwas, wenn diese Trennung geschieht.

  3. Wenn die Socket-Verbindung i hatte wurde dann ungültig, warum die recv() Socket-Funktion Wurf und SOCKET_ERROR tut. Stattdessen Warum erhalte ich Daten von 0 Länge.

Dank

+0

Haben Sie auf der Remote-Seite shutdown() aufgerufen? Das wird recv 0 zurückgeben: http://StackOverflow.com/questions/2843277/c-winsock-p2p/2920787#2920787 – Default

Antwort

31

Wenn recv einen Wert von 0 zurückgibt, der die Verbindungsmittel werden geschlossen.

anzeigen recv man page:

Diese Anrufe die Anzahl der empfangenen Bytes zurück oder -1, wenn ein Fehler aufgetreten . Der Rückgabewert ist 0, wenn der Peer eine ordnungsgemäße Abschaltung durchgeführt hat.

In Antwort auf Frage 1, ja der Socket ist jetzt ungültig. Sie müssen einen neuen Socket und eine neue Verbindung für die weitere Kommunikation erstellen.

bearbeiten

Jetzt als valdo unten erwähnt, gibt es auch die Möglichkeit, eine halbgeschlossene TCP-Verbindung zu haben, in dem Sie nicht mehr empfangen können, aber Sie können, bis Sie an die Buchse Schreiben halten Haben Sie Ihre Daten gesendet? Siehe diesen Artikel für weitere Details: TCP Half-Close. Es klingt nicht so, als hättest du diese Situation.

In Antwort # 2, gibt es grundsätzlich zwei Möglichkeiten in Frage eine geschlossene Buchse zu erkennen. Dies setzt voraus, dass der Socket ordnungsgemäß heruntergefahren wurde, was bedeutet, dass der Peer entweder shutdown oder close heißt.

Die erste Methode ist das Lesen aus dem Socket. In diesem Fall erhalten Sie den Rückgabewert 0. Die andere Methode besteht darin, in den Socket zu schreiben, wodurch das Signal SIG_PIPE ausgelöst wird, was auf eine defekte Pipe hinweist.

Um das Signal zu vermeiden, können Sie die MSG_NOSIGNAL Socket-Option festgelegt, in dem Fall send zurückkehren würde -1 und setzte errno-EPIPE.

+0

Also was ich tun muss, ist, wenn ich einen Rückgabewert von 0 bekomme, dann muss ich das schließen Steckdose und eine andere Steckdose öffnen, oder? – ckv

+0

@cvk - Korrekt. –

+1

Warum hat jemand diese Antwort markiert? –

2

Wenn recv 0 zurück, das bedeutet, dass der Peer die Socket geschlossen hat.

recv nicht, weil seine eine C-Funktion werfen.

Wenn ein Fehler auftritt, wird recv -1 zurückgeben. In diesem Fall muss Ihre Anwendung die Art des Fehlers überprüfen. Beachten Sie, dass eine Rückgabe von -1 nicht bedeutet, dass der Peer den Socket geschlossen hat.

1

Da Sie mit einem Webserver sprechen, nehme ich an, dass Sie TCP-Sockets verwenden.

zu beantworten:

  1. Sockets aufgrund einer disconnect nicht ungültig; Sie gehen einfach in einen getrennten Zustand. Es ist immer noch sicher, Socket-Operationen auf ihnen aufzurufen.

  2. Sie erhalten keine speziellen Nachrichten, wenn die Verbindung getrennt wird. Wenn Sie recv() in einer blockierenden Weise aufrufen, wird es zurückgegeben, wenn die Verbindung unterbrochen wird, und die Anzahl der Bytes, die von dem Aufruf zurückgegeben werden, stimmt nicht mit der Anzahl der Bytes überein, nach denen Sie gefragt haben.

  3. Es gibt nicht wirklich eine Antwort auf diese - es ist, wie die Socket-API ursprünglich implementiert wurde, und wir stecken fest mit dieser Implementierung als alle implementiert Berkley Sockets.

3

Ich nehme an, dass Sie TCP verwenden, um mit Ihrem Gerät zu kommunizieren.

  1. Der Socket selbst ist immer noch "gültig", aber die Verbindung ging verloren.

  2. Sie einen Rückgabewert von 0 für recv() erhalten, wenn die Verbindung durch den anderen Host geschlossen wurde (ob diese Trennung anmutig war oder nicht spielt keine Rolle)

  3. Socket-Funktionen sind wie C Funktionen: sie don 't werfen, weil sie in C Programmen verwendet werden können, wo Ausnahmen nicht existieren.

8

Stimmen Sie mit Robert S. Barnes überein. Außer der Behauptung, dass der Sockel jetzt "ungültig" ist.

Es ist immer noch gültig. Du kannst es benutzen. Sie können sogar Daten an den Peer senden. Das einzige, was Sie damit nicht tun können, ist Anruf recv.

+1

+1 Richtig, ich habe die Möglichkeit eines halbnahen vergessen. Ich werde meine Antwort aktualisieren. –

+0

Wollte darauf hinweisen, dass dies davon abhängt, ob der Peer 'close' aufgerufen hat oder nicht, oder halbwegs geschlossen hat, indem er' shutdown' mit dem 'SHUT_WR'-Flag aufgerufen hat. Siehe die 'shutdown'-Hilfeseite: http://www.kernel.org/doc/man-pages/online/pages/man2/shutdown.2.html –

Verwandte Themen