In meinem Clientcode befolge ich diese Schritte, um eine Verbindung zu einem Socket herzustellen:
Einen Socket erstellen
%Vor%Verbinden Sie es (versuchen Sie es im Fehlerfall erneut mit "x")
%Vor% (Nach dem Füllen der Felder destAddr
)
Verwenden des Sockets für send()
/ recv()
Operation:
close()
der Socket-Deskriptor und beenden
Wenn während send()
/ recv()
die Verbindung unterbrochen wird, konnte ich eine Verbindung herstellen, indem ich zu Schritt 2 zurückkehre.
Ist diese Lösung in Ordnung? Soll ich den Socket-Deskriptor schließen und zu Schritt 1 zurückkehren?
Eine weitere interessante Beobachtung, die ich nicht verstehen kann, ist wann
Ich stoppe meinen Echo-Server und starte den Client. Ich erstelle einen Socket (Schritt 1) und rufe connect()
auf, was fehlschlägt (wie erwartet), aber dann rufe ich connect()
an, sagen wir mal 10 mal. Nach 5 Versuchen starte ich den Server und connect()
ist erfolgreich. Aber während des Aufrufs send()
erhält er SIGPIPE
error. Ich würde gerne wissen:
1) Muss ich jedes Mal, wenn connect()
fehlschlägt, einen neuen Socket erstellen? Soweit ich weiß, solange ich keine send()
/ recv()
auf dem Socket ausgeführt habe, ist es so gut wie neu und ich kann dasselbe fd
für den connect()
Aufruf wiederverwenden.
2) Ich verstehe nicht, warum SIGPIPE
empfangen wird, wenn der Server aktiv ist und connect()
erfolgreich ist.
Ja, Sie sollten schließen und zu Schritt 1 zurückkehren:
close () schließt einen Dateideskriptor, damit es sich nicht mehr auf irgendwelche bezieht Datei und kann wiederverwendet werden.
Von hier .
Steckdosen, die einer unterbrochenen Verbindung entsprechen, befinden sich in einem instabilen Zustand. Normalerweise ist es nicht erlaubt, sich erneut zu verbinden, es sei denn, das Betriebssystem gibt den Socket frei.
Ich denke, es ist besser zu schließen () und wieder verbinden .. Sie müssen nicht einen anderen Sockel erstellen.
Stellen Sie auf jeden Fall LINGER Ihres Sockets ein, um sicherzustellen, dass keine Daten in der Übertragung verloren gehen.
Siehe Ссылка
Ich denke, das Schließen der Steckdose ist die richtige Sache, obwohl es funktioniert, wenn Sie es nicht tun.
Ein Socket, bei dem die Verbindung fehlgeschlagen ist, befindet sich möglicherweise nicht GENAU im selben Zustand wie ein brandneues - was später Probleme verursachen könnte. Ich würde lieber die Möglichkeit vermeiden und einfach eine neue machen. Es ist sauberer.
TCP-Sockets enthalten eine Vielzahl von Zuständen, von denen einige implementierungsspezifisch sind und aus dem Netzwerk ausgearbeitet wurden.
Wenn die Verbindung unterbrochen wurde und Sie versuchen, auf den Dateideskriptor zu schreiben, sollten Sie den gebrochenen Rohrfehler / Signal erhalten. All dies besagt, dass der Dateideskriptor, an den Sie schreiben wollten, niemanden mehr auf der anderen Seite hat, der liest, was Sie senden.
Was Sie tun können, ist das Signal SIGPIPE zu fangen und dann die Wiederverbindung durch Schließen der FD und Zurückgehen zu Ihrem Schritt 1 zu bewältigen. Sie werden nun eine neue FD haben, von der Sie für die Verbindung lesen und schreiben können.
Wenn die Single UNIX Specification nicht besagt, dass es notwendig ist, zu Schritt # 2 anstatt zu Schritt # 1 zurückzukehren, dann ist die Tatsache, dass es zufällig unter Linux funktioniert, nur ein Implementierungsdetail, und Sie wären weit entfernt besser und portabler, wenn Sie zu Schritt # 1 zurückkehren. Soweit mir bekannt ist, gibt die Spezifikation keine Garantie, dass es in Ordnung ist, zu Schritt 2 zurückzukehren, und daher würde ich Ihnen empfehlen, zu Schritt 1 zurückzukehren.