Jestem trochę zdezorientowany przez róg obfitości powiązanych metod na obiekcie Socket, który rzekomo zamyka i czyści połączenie przez gniazdo. Rozważmy następujący:Jaki jest właściwy sposób zamykania i czyszczenia połączenia z gniazdem?
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();
Ponadto this guy mówi, że aby naprawdę czysto zamknąć połączenie, należy wykonać socket.Shutdown(SocketShudown.Send)
, a następnie czekać na drugą stronę, aby odpowiedzieć.
Jaki jest prawidłowy sposób zamknięcia, a następnie wyczyścić połączenie gniazda?
Ten facet ma połowę rację. Myślę, że to zależy od protokołu między tymi dwoma. Jeśli spodziewasz się, że będziesz w stanie odbierać przez pewien czas, to tak, powinieneś powiedzieć drugiej stronie o zamiarze zamknięcia i powiedzieć, że przestaniesz wysyłać, ale nadal możesz otrzymywać. – uriDium
"ten facet" jest w większości poprawny, ponieważ podobnie modelowałem swój kod serwera. Uważam jednak, że podejście "półzbliżenie-potem-czekanie" jest konieczne tylko w przypadku asynchronicznych (nieblokujących) gniazd. Wierzę, że w przypadku gniazd nieblokujących, wywołujesz "Wyślij", a zaraz po tym Close, istnieją pewne warunki brzegowe, w których może nastąpić utrata danych, jeśli są pakiety, które muszą zostać ponownie przesłane. – selbie
Użyłem podejścia hybrydowego z moim serwerem gniazd. Serwer najpierw zamknie połowicznie połączenie i poczeka, aż recv() zwróci 0 lub błąd, aby wskazać, że klient jest gotowy. Mam jednak zegar, który okresowo wyłącza się co 45 sekund, aby zamiatać i zamykać wszelkie półotwarte połączenia, które utrzymywały się od ostatniego przemiatania. – selbie