Arresto tolleranza, opzioni di linger e chiusura socket

Il materiale seguente viene fornito come chiarimento per il soggetto dell'arresto delle connessioni socket che chiude i socket. È importante distinguere la differenza tra l'arresto di una connessione socket e la chiusura di un socket.

L'arresto di una connessione socket comporta uno scambio di messaggi di protocollo tra i due endpoint, qui di seguito denominata sequenza di arresto. Vengono definite due classi generali di sequenze di arresto: grazia e interruzione (anche denominata hard). In una sequenza di arresto grazia, tutti i dati accodati, ma non ancora trasmessi possono essere inviati prima della chiusura della connessione. In un arresto interrotto, tutti i dati non inviati si perdono. L'occorrenza di una sequenza di arresto (grazia o interruzione) può essere usata anche per fornire un FD_CLOSE indicazione alle applicazioni associate che indicano che un arresto è in corso.

La chiusura di un socket, invece, causa la deallocazione del socket in modo che l'applicazione non possa più fare riferimento o usare il socket in alcun modo.

In Windows Sockets, sia la funzione di arresto che la funzione WSASendDisconnect può essere usata per avviare una sequenza di arresto, mentre la funzione closesocket viene usata per deallocare gli handle del socket e liberare qualsiasi risorsa associata. Tuttavia, una certa quantità di confusione si verifica dal fatto che la funzione closesocket causa in modo implicito una sequenza di arresto se non è già successo. Infatti, è diventata una pratica di programmazione piuttosto comune per basarsi su questa funzionalità e usare closesocket per avviare la sequenza di arresto e deallocare l'handle del socket.

Per facilitare l'utilizzo, l'interfaccia socket fornisce i controlli tramite il meccanismo di opzione socket che consente al programmatore di indicare se la sequenza di arresto implicita deve essere graziata o interrotta e anche se la funzione closesocket deve rimanere persistente (che non è completata immediatamente) per consentire il completamento di una sequenza di arresto grazia. Queste importanti distinzione e le ramificazioni dell'uso di closesocket in questo modo non sono ancora ampiamente comprese.

Definendo i valori appropriati per le opzioni socket SO_LINGER e SO_DONTLINGER, è possibile ottenere i tipi di comportamento seguenti con la funzione closesocket :

  • Sequenza di arresto interrotta, ritorno immediato da closesocket.
  • Arresto normale, ritardo restituito fino al completamento della sequenza di arresto o di un intervallo di tempo specificato trascorso. Se l'intervallo di tempo scade prima del completamento della sequenza di arresto graziata, si verifica una sequenza di arresto interrotta e closesocket restituisce.
  • Arresto normale, ritorno immediato, che consente di completare la sequenza di arresto in background. Anche se si tratta del comportamento predefinito, l'applicazione non ha modo di sapere quando (o se) la sequenza di arresto grazia viene effettivamente completata.

L'uso delle opzioni di SO_LINGER e del socket SO_DONTLINGER e la struttura del socket associata viene illustrata in modo più dettagliato nelle sezioni di riferimento in SOL_SOCKET Opzioni socket e nella struttura di linger .

Una tecnica che può essere usata per ridurre al minimo la probabilità di problemi durante il teardown della connessione consiste nell'evitare di basarsi su un arresto implicito avviato da closesocket. Usare invece una delle due funzioni di arresto esplicite, arresto o WSASendDisconnect. Ciò a sua volta causa la ricezione di un'indicazione FD_CLOSE dall'applicazione peer che indica che tutti i dati in sospeso sono stati ricevuti. Per illustrare questa operazione, la tabella seguente mostra le funzioni che verranno richiamate dai componenti client e server di un'applicazione, in cui il client è responsabile dell'avvio di un arresto graziato.

Lato client Sul lato server
(1) Richiama gli arresti, SD_SEND) per segnalare la fine della sessione e che il client non ha più dati da inviare.
(2) Riceve FD_CLOSE, che indica l'arresto normale in corso e che tutti i dati sono stati ricevuti.
(3) Invia i dati di risposta rimanenti.
(solo significato di intervallo locale) Ottiene FD_READ e chiama recv per ottenere i dati di risposta inviati dal server . (4) Richiama gli arresti, SD_SEND) per indicare che il server non ha più dati da inviare.
(5) Riceve FD_CLOSE indicazione. (solo significato di intervallo locale) Richiama closesocket .
(6) Richiama closesocket.