Socket-Deskriptor bei Verbindungsausfall erneut verwenden

8

In meinem Clientcode befolge ich diese Schritte, um eine Verbindung zu einem Socket herzustellen:

  1. Einen Socket erstellen

    %Vor%
  2. Verbinden Sie es (versuchen Sie es im Fehlerfall erneut mit "x")

    %Vor%

    (Nach dem Füllen der Felder destAddr )

  3. Verwenden des Sockets für send() / recv() Operation:

    %Vor%
  4. close() der Socket-Deskriptor und beenden

    %Vor%

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.

    
Adil 10.02.2010, 14:32
quelle

5 Antworten

5

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 .

    
Hassan Syed 10.02.2010, 14:49
quelle
4

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 Ссылка

    
Yousf 10.02.2010 14:50
quelle
4

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.

    
MarkR 10.02.2010 23:05
quelle
2

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.

    
Chris 10.02.2010 15:50
quelle
2

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.

    
Michael Aaron Safyan 10.02.2010 21:56
quelle

Tags und Links