2015-04-27 7 views
8

Ich möchte einen einfachen, kleinen C++ RAII-Wrapper über einen C-Sockel schreiben.RAII-Sockets: Wann freigeben (schließen)

Die Frage ist, in welchem ​​Zustand ein Socket als initialisiert betrachtet wird (aus der Perspektive von RAII) und so für die Freigabe in Frage kommt.

Zum Beispiel für einen TCP-Client-Socket: Wenn der socket Aufruf erfolgreich ist, aber der connect Aufruf fehlgeschlagen ist, sollte close aufgerufen werden?

Dies ist nur ein Beispiel, Ich interessiere mich für eine allgemeine Antwort, so etwas wie:

  • Jeder Sockel erfolgreich durch socket erstellt wurden, müssen geschlossen werden.
    oder
  • Es muss für jedes connect, listen oder accept eine Schließung geben.

Der Man-Pages für socket & Freunde und close ist nicht ganz klar (oder zumindest für mich).

+0

Wenn Sie ein gültiges/aktives Socket-Handle haben, wird es initialisiert. –

+0

@CaptainObvlious Wann wird ein Socket-Handle als vaid/active betrachtet? – bolov

+0

Das Socket-Handle ist gültig, wenn "Socket" oder "accept" einen anderen Wert als "INVALID_SOCKET" zurückgibt und bis Sie den Handle "schließen". –

Antwort

3

Die zwei zu paarenden Teile für Steckdosen sind socket() mit close() und connect() mit shutdown(). Wie Sie sehen, wird es nicht so einfach wie mit malloc() und free(). Dies wird zusätzlich dadurch erschwert, dass nicht jede Buchse an connect() gewöhnt ist, sondern auch einige bind() und accept(). Wenn Sie jedoch close() ohne shutdown() aufrufen, ist es nur ein energisches Herunterfahren, das als ein Fehler von der Remoteseite erfahren wird, aber Sie geben ordnungsgemäß Ressourcen frei, die zugewiesen wurden.

Ich würde in Betracht ziehen, es zweimal zu umhüllen, einmal, um close() aufzurufen und ein anderes Mal, um shutdown() aufzurufen. Über den zweiten Teil würde ich mich jedoch nicht zu viele Gedanken machen, da das Scheitern von shutdown() immer noch größtenteils harmlos ist.

+0

für 'bind' und' accept' sollte Shutdown aufgerufen werden? – bolov

+0

@bolov: Wie Ulrich sagt, müssen Sie sich nicht zu viele Gedanken über den Aufruf von 'shutdown' machen, da dies nicht zu Ressourcenverlusten führt. Also würde ich es nicht mit RAII einpacken. Die Regel unter Unix ist ziemlich einfach: Wenn irgendein Aufruf einen Dateideskriptor> = 0 zurückgibt ('open',' socket', 'accept',' dup' ...), müssen Sie ihn schließen, um ein Ressourcenleck zu vermeiden . – Nemo