2015-04-27 17 views
8

Voglio scrivere un wrapper C++ RAII semplice e piccolo su un socket C.Prese RAII: quando rilasciare (chiuso)

La domanda è in quale stato è un socket considerato inizializzato (dal punto di vista di RAII) e quindi idoneo per il rilascio.

Ad esempio, per un socket client TCP: se la chiamata socket ha esito positivo, ma la chiamata connect non è riuscita, è necessario chiamare close?

Questo è solo un esempio, io sono interessato a una risposta generale, qualcosa di simile:

  • Ogni socket creato con successo da socket deve essere chiuso.
    o
  • Ci deve essere una chiusura per ogni connect, listen o accept.

Le pagine man per socket & amici e close non sono molto chiare (o almeno a me).

+0

Se si dispone di un handle di socket valido/attivo, è stato inizializzato. –

+0

@CaptainObvlious Quando un handle del socket è considerato vaid/active? – bolov

+0

L'handle del socket è valido quando 'socket' o' accept' restituiscono un valore diverso da 'INVALID_SOCKET' e finché non si chiude l'handle. –

risposta

3

Le due parti da accoppiare per prese sono socket() con close() e connect() con shutdown(). Come vedi, non è facile come con malloc() e free(). Ciò è ulteriormente complicato dal fatto che non tutti i socket vengono utilizzati per connect(), alcuni utilizzano anche bind() e accept(). Tuttavia, se si chiama close() senza shutdown(), si tratta solo di un arresto forzato che viene rilevato come errore dal lato remoto, ma si rilasciano correttamente le risorse allocate.

Prenderei in considerazione il wrapping due volte, una volta per invocare close() e un'altra volta per richiamare shutdown(). Non mi preoccuperei troppo della seconda parte, anche se il fallimento di shutdown() è ancora in gran parte innocuo.

+0

per 'bind' e' accept' dovrebbe essere chiamato shutdown? – bolov

+0

@bolov: come dice Ulrich, non è necessario preoccuparsi troppo di chiamare 'shutdown', in caso contrario non si verificheranno perdite di risorse. Quindi non mi preoccuperei di avvolgerlo con RAII. La regola su Unix è piuttosto semplice: se una chiamata restituisce un descrittore di file> = 0 ('open',' socket', 'accept',' dup' ...), devi 'chiudere' per evitare una perdita di risorse . – Nemo