Mevcut cevapların hiçbiri insanlara TCP protokolü düzeyinde nasıl çalıştığını shutdown
ve close
çalıştığını söylemediğinden , bunu eklemeye değer.
Standart TCP bağlantısı 4 yönlü sonlandırma ile sonlandırılır:
- Bir katılımcı gönderilecek daha fazla veriye sahip olmadığında, diğerine bir FIN paketi gönderir
- Diğer taraf FIN için bir ACK döndürür.
- Karşı taraf da veri aktarımını bitirdiğinde, başka bir FIN paketi gönderir
- İlk katılımcı bir ACK döndürür ve aktarımı sonlandırır.
Ancak, TCP bağlantısını kapatmanın başka bir "acil" yolu vardır:
- Bir katılımcı bir RST paketi gönderir ve bağlantıdan çıkar
- Diğer taraf bir RST alır ve bağlantıyı da terk eder
Wireshark ile yaptığım testte, varsayılan soket seçenekleriyle, shutdown
diğer uca bir FIN paketi gönderir , ancak hepsi bu. Karşı taraf size FIN paketini gönderene kadar hala veri alabilirsiniz. Bu gerçekleştiğinde, Receive
0 boyutta bir sonuç elde edersiniz. Dolayısıyla, "gönder" i ilk kapatan sizseniz, veri almayı bitirdiğinizde soketi kapatmalısınız.
Öte yandan, close
bağlantı hala etkinken ararsanız (diğer taraf hala aktiftir ve sistem arabelleğinde gönderilmemiş verileriniz olabilir), diğer tarafa bir RST paketi gönderilir. Bu hatalar için iyidir. Örneğin, karşı tarafın yanlış veri sağladığını veya veri sağlamayı reddettiğini (DOS saldırısı?) Düşünüyorsanız, soketi hemen kapatabilirsiniz.
Kurallar hakkındaki görüşüm:
- Mümkün olduğunca
shutdown
önce düşününclose
- Kapatmaya karar vermeden önce (0 boyutlu veri alındı) almayı bitirdiyseniz, son gönderim (varsa) bittikten sonra bağlantıyı kapatın.
- Bağlantıyı normal olarak kapatmak istiyorsanız, bağlantıyı kapatın (SHUT_WR ile ve bu noktadan sonra SHUT_RD ile veri almayı umursamıyorsanız) ve 0 boyutlu veri alana kadar bekleyin ve ardından priz.
- Her durumda, başka bir hata oluşursa (örneğin zaman aşımı), soketi kapatmanız yeterlidir.
SHUT_RD ve SHUT_WR için ideal uygulamalar
Aşağıdakiler test edilmemiştir, kendi sorumluluğunuzdadır. Ancak, bunun bir şeyler yapmanın makul ve pratik bir yolu olduğuna inanıyorum.
TCP yığını yalnızca SHUT_RD ile kapatma alırsa, bu bağlantı daha fazla veri beklenmiyor olarak işaretlenir. Bekleyen ve sonraki read
istekler (hangi iş parçacığında olursa olsunlar) daha sonra sıfır boyutlu sonuç döndürür. Ancak, bağlantı hala etkin ve kullanılabilir - örneğin, yine de OOB verilerini alabilirsiniz. Ayrıca, işletim sistemi bu bağlantı için aldığı verileri bırakacaktır. Ama hepsi bu, diğer tarafa hiçbir paket gönderilmeyecek.
TCP yığını yalnızca SHUT_WR ile kapatma alırsa, daha fazla veri gönderilemediğinden bu bağlantı işaretlenecektir. Bekleyen tüm yazma istekleri tamamlanacak, ancak sonraki yazma istekleri başarısız olacaktır. Ayrıca, gönderilecek daha fazla veriye sahip olmadığımızı bildirmek için başka bir tarafa bir FIN paketi gönderilecektir.