В результате соединение рвется, во всяком случае сервер фиксирует отключение (сервер и клиент находятся на одном ПК), но есть НО.
Пишу команду netstat и вижу, что соединение существует, но только в статусе TIME_WAIT
С одной стороны: НУ И ПУСТЬ! СО ВРЕМЕНЕМ ЗАКРОЕТСЯ! а с другой стороны, порт то занят + осадок на душе остаётся)))
Подскажите, кто с такой проблемой сталкивался, как решали?
Здравствуйте, SanyaVB, Вы писали:
SVB>Пишу команду netstat и вижу, что соединение существует, но только в статусе TIME_WAIT SVB>С одной стороны: НУ И ПУСТЬ! СО ВРЕМЕНЕМ ЗАКРОЕТСЯ! а с другой стороны, порт то занят + осадок на душе остаётся))) SVB>Подскажите, кто с такой проблемой сталкивался, как решали?
Это не проблема, а фича. Если сразу освободить порт и переподключиться, есть риск получить соединение с тем же портом и получить какой-нибудь застрявший пакет со старого соединения.
Но если очень хочется, то есть опция System.Net.Sockets.LingerOption, которая определяет сколько времени сокет провисит в TIME_WAIT, и эту опцию нужно записать в свойство Socket.LingerState.
Здравствуйте, Xander Zerge, Вы писали:
XZ>Это не проблема, а фича. Если сразу освободить порт и переподключиться, есть риск получить соединение с тем же портом и получить какой-нибудь застрявший пакет со старого соединения.
ОГО! Спасибо! Не знал такого...
XZ>Но если очень хочется, то есть опция System.Net.Sockets.LingerOption, которая определяет сколько времени сокет провисит в TIME_WAIT, и эту опцию нужно записать в свойство Socket.LingerState.
Здравствуйте, SanyaVB, Вы писали:
SVB>Пишу команду netstat и вижу, что соединение существует, но только в статусе TIME_WAIT SVB>С одной стороны: НУ И ПУСТЬ! СО ВРЕМЕНЕМ ЗАКРОЕТСЯ! а с другой стороны, порт то занят + осадок на душе остаётся)))
Это так и должно быть. TCP так устроен. Сокет на той стороне, которая первая сказала close(), остается на 40 секунд в состоянии TIME_WAIT.
Если у тебя клиент-серверное приложение, и протокол выбираешь ты, лучше определить протокол таким образом, чтобы соединение закрывали клиенты. У них таких соединений будет немного, а на стороне сервера может заметное количество накопиться.
Но есть еще одна вещь, которую ты не учитываешь. Закрытие сокета — операция, по умолчанию, блокирующаяся, и может занять какое-то время (в среднем полсекунды, но при неудачном раскладе и до десятков секунд может дойти).
Если для твоей задачи это критично, есть смысл об этом подумать.
Здравствуйте, SanyaVB, Вы писали:
SVB>С одной стороны: НУ И ПУСТЬ! СО ВРЕМЕНЕМ ЗАКРОЕТСЯ! а с другой стороны, порт то занят + осадок на душе остаётся)))
в общем случае этого сделать нельзя и не нужно.
Есои волнует занятость порта и потенциалньые пробелмы с безопасностью не волнуют — SO_REUSEADDR в помощь