Я делаю некоторые тесты, пытаясь изолировать некоторые странные поведения в библиотеках (.NET). Когда я использую Winsock API через C++ и просто вызываю closesocket()
, я вижу, что сторона Windows отправляет пакет FIN/ACK, а удаленная сторона отправляет обратно пакет ACK. Это то, что я бы назвал грациозным закрытием. Тем не менее, при программировании на С# я не вижу того, что я бы назвал грациозным закрытием.
В С# я открываю свой сокет и затем, закрывая его, я вижу, что окна отправляют пакет FIN только при первом вызове Socket.Shutdown()
. Однако независимо от того, когда я вызываю Socket.Close()
в С#, отправляется пакет RST, и соединение Socket.Close()
. Это сбивает меня с толку, потому что из того, что я прочитал в режиме онлайн, процесс закрытия TCP должен быть FIN/ACK → ACK (на самом деле с обеих сторон, но сейчас меня интересует только "моя" сторона); т.е. в миксе не должно быть пакета RST. Из того, что я прочитал, по-видимому, пакет RST отправляется только тогда, когда получатель не уверен в состоянии соединения и хочет выйти.
Почему этот пакет RST отправляется при плановом завершении работы в .NET, а не при запланированном завершении работы из Winsock API? Есть ли способ предотвратить передачу пакета RST во время постепенного завершения работы из .NET?
В случае, если это важно, в обоих путях кода я читаю все доступные данные в сокете перед вызовом соответствующего метода close()
.