2009-04-23 3 views
2

Ich habe Client/Server-Programm in C, durch die ich Dateien vom Server auf den Client übertragen.Socket: Client wartet auch nach Erhalt letzten Byte

Aber der Client wartet auf recv, auch nachdem das letzte Byte der Datei empfangen wurde. Client beendet nur, wenn ich es töte oder Server von mir getötet wird. Aber Server muss in einer Schleife sein, wie es die Anfrage anderer Clients zu unterhalten.

Ich verwende fork() im Server, um die Anfrage jedes Clients zu unterhalten. Ich verlasse den Kindprozess, nachdem die Anfrage des Clients unterhalten wurde, aber der Client wird nur beendet, wenn das gesamte Serverprogramm beendet wird.

Warum beendet der Client nicht, wenn das Kind des Servers beendet wird?

Sie können den Servercode here und den Clientcode here sehen.

+2

Was ist Ihre Frage? – JRL

+0

@JRL geben -1 ohne Grund für eine gültige Frage ist sehr schlecht !!, Frage ist richtig. –

+0

@Akash: Ich verstehe nicht, was Sie sagen. Wenn du sagst, dass ich -1 gegeben habe, liegst du falsch, ich nicht. Ich habe mich nur gefragt, was seine Frage war. – JRL

Antwort

3

Sie sollten sicherstellen, dass Sie shutdown(s, SHUT_WR nennen), gefolgt von close(s) im Serverprozess einmal alle Daten gesendet wurde.

Der Aufruf an shutdown() teilt der TCP-Schicht mit, dass keine Daten mehr gesendet werden müssen.

TBH, ich bin mir nicht ganz sicher, warum das Rufen von close() allein nicht auch das erreicht.

BEARBEITEN - Ich habe das jetzt herausgefunden - es ist, weil an diesem Punkt in Ihrem Code der Elternteil immer noch den Sockel geöffnet hat, damit er nicht vom Kernel abgerissen wird. Wenn nach dem fork() Sie einige zusätzliche Logik hinzufügen:

if (p > 0) { 
    close(connected); 
} 

dann funktioniert der Code ohne Aufruf zu shutdown().

Wenn Sie den Code verwenden, den ich in my answer zu Ihrer Frage von gestern gesendet habe, dann erhält der Client eine bytes_received Zählung von Null und beendet dann seine Schleife.

+0

danke für deine Antwort! sind die gemeinsame Datei von Eltern und Kind, sobald ich durch das Kind in der Nähe verbunden habe, denke ich sollte funktionieren. übrigens, wie Sie sagten, sobald der Client null Bytes erhalten hat, wird es aus seiner Schleife kommen und wird schließlich beenden. Aber es ist nicht passiert, Kind wartet auf etwas auch nach dem Empfang all.I hv legte auch printf in die Schleife aber Es zeigt nichts, bis der Server getötet wird! – mawia

+0

Nein, die Datei wird freigegeben, aber die Dateideskriptoren sind getrennt. Wenn Sie es im Kind schließen, bleibt es im Elternteil geöffnet. Da die Datei immer noch geöffnet ist, sendet der Server niemals den Nulllängenindikator für das End-of-Stream. Ich habe den Code oben zu Ihrem Server-Programm hinzugefügt und dann hat alles gut funktioniert. – Alnitak

0

Sie sollten etwas anrufen wie: shutdown (s, SD_SEND); Verschlusshülse (n);

auf dem Server nach dem Senden der Datei, um den Socket zu schließen.

0

Dies ist ein bisschen schwer, mehr Details wäre nett. Verwenden Sie TCP/IP? Da Sie über Dateiübertragungen sprechen, nehme ich an, es ist TCP.

Wenn Sie den Prozess auf der Serverseite beenden, die den mit dem Client verbundenen Socket besitzt, sollte dies zum Abbruch der Verbindung führen. Der Anruf des Kunden recv() sollte dann beenden und -1 zurückgeben (oder 0, nicht 100% sicher). Wenn Sie dies nicht tun, schauen Sie sich den Socket im Hauptserverprozess explizit an (nicht sicher, wie Sie Ihre Socket-Eigentümerschaft eingerichtet haben).

-1

Es gibt zwei Lesarten Steckdosen ...

  1. Empfangen Byte für Byte mit recv(), aber Problem ist, wenn Sie Ihre Inhalte enthält -1 in der Mitte Ihrer Daten dann wird es zeigen Ende Datei.

  2. Eine andere Möglichkeit besteht darin, Puffer aus dem Stream zu lesen, und diese Methode gibt die Anzahl der aus dem Stream gelesenen Bytes zurück, und wenn diese 0 zurückgibt, bedeutet dies das Ende des Streams.

+0

-1 für den komplett falschen Punkt ca. -1 in der Mitte der Datei – Alnitak

+0

Ein Funktionsaufruf pro Byte ist echt nervig! Sie müssen es besser machen. –

Verwandte Themen