Я знаю, что TIME_WAIT является неотъемлемой частью TCP/IP, но есть много вопросов о SO (и других местах), где в секунду создается несколько сокетов, а сервер заканчивается из эфемерных портов.
То, что я узнал, заключается в том, что при использовании TCPClient
(или Socket
, если на то пошло), если я вызываю либо методы Close()
, либо Dispose()
, состояние TCP-сокета изменяется на TIME_WAIT и будет уважать таймаут период до полного закрытия.
Однако, если он просто установил переменную в null
, сокет будет полностью закрыт при следующем запуске GC, который, конечно же, может быть принудительно, без какого-либо состояния TIME_WAIT.
Это не имеет большого значения для меня, так как это объект IDisposable
не должен GC также вызывать метод Dispose()
объекта?
Здесь приведен код PowerShell, который демонстрирует, что (на этой машине нет VS). Я использовал TCPView от Sysinternals для проверки состояния сокетов в реальном времени:
$sockets = @()
0..100 | % {
$sockets += New-Object System.Net.Sockets.TcpClient
$sockets[$_].Connect('localhost', 80)
}
Start-Sleep -Seconds 10
$sockets = $null
[GC]::Collect()
Используя этот метод, сокеты никогда не входят в состояние TIME_WAIT. То же самое, если я просто закрою приложение перед ручным вызовом Close()
или Dispose()
Может кто-то пролить свет и объяснить, будет ли это хорошей практикой (что, я думаю, люди скажут это не так).
ИЗМЕНИТЬ
Вопрос GC в этом вопросе уже был дан, но мне все еще интересно узнать, почему это повлияет на состояние сокета, поскольку это должно контролироваться ОС, а не .NET.
Также интересно узнать, было ли хорошей практикой использовать этот метод для предотвращения состояний TIME_WAIT и, в конечном счете, является ли это ошибкой где-нибудь (т.е. должны ли все сокеты проходить через состояние TIME_WAIT?)