2013-03-12 14 views
17

Sono un po 'confuso dalla cornucopia dei metodi correlati sull'oggetto Socket che presumibilmente chiude e pulisce una connessione socket. Si consideri il seguente:Qual è il modo corretto di chiudere e pulire una connessione Socket?

var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
socket.Connect("192.168.1.22", 8333); 
socket.Send(Encoding.UTF8.GetBytes("hello")); 

// now for the closing fun 
socket.Shutdown(SocketShutdown.Both); 
socket.Disconnect(false); 
socket.Close(); 
socket.Dispose(); 

Inoltre, this guy dice che davvero in modo pulito chiudere una connessione, è necessario effettuare socket.Shutdown(SocketShudown.Send), quindi attendere che l'altro lato di rispondere.

Qual è il modo corretto per chiudere, quindi pulire una connessione socket?

+0

Quel ragazzo ha ragione a metà. Penso che dipenda dal protocollo tra i due. Se ti aspetti di riuscire ancora a ricevere per un po 'di tempo allora sì, dovresti dire al tuo interlocutore che hai intenzione di fermarti e dire che smetterai di inviare ma puoi ancora ricevere. – uriDium

+0

"quel ragazzo" è per lo più corretto, come ho modellato il mio codice server in modo simile. Ma credo che l'approccio half-close-then-wait sia necessario solo per i socket asincroni (non bloccanti). Credo che nel caso di socket non bloccanti, si chiami "Send" seguito immediatamente da Close, ci sono alcune condizioni limite in cui può verificarsi una perdita di dati se ci sono pacchetti che devono essere ritrasmessi. – selbie

+0

Ho usato un approccio ibrido con il mio server socket. Il server chiuderà per metà la connessione e attenderà che recv() restituisca 0 o errore per indicare che il client ha finito. Tuttavia, ho un timer che si spegne periodicamente ogni 45 secondi per spazzare e chiudere le connessioni semiaperte che sono rimaste in sospeso dall'ultima scansione. – selbie

risposta

11

presa Chiusura chiude la connessione, e chiudere un involucro metodo Dispose intorno, così generalmente

socket.Shutdown(SocketShutdown.Both); 
socket.Close(); 

dovrebbe essere sufficiente. Qualcuno potrebbe obiettare che l'implementazione Chiudi potrebbe cambiare un giorno (quindi non chiama più Dispose), e si dovrebbe chiamare Dispose manualmente dopo aver chiamato Close, ma dubito che succederà, personalmente :)

In alternativa, si consideri l'utilizzo di (sì):

using (var socket = new Socket(...)) 
{ 
    .... 
    socket.Shutdown(SocketShutdown.Both); 
} 
Problemi correlati