Как определить, что TCP сессия была закрыта на другом конце - C#

Узнай цену своей работы

Формулировка задачи:

Пишу реализацию сетевого протокола, который работает поверх TCP/IP. Протокол работает по принципу клиент-сервер. Клиент начинает TCP сессию, внутри сессии отправляет запрос, сервер только шлет ответ на запрос. Пар запрос-ответ внутри сессии может быть сколько угодно, сессия по продолжительности не ограничена и завершается на стороне клиента. Сервер многопоточный, поддерживает несколько сессий. Пишу серверную часть, вопросы по ней. Стартую TcpListener и жду соединения методом Listener.AcceptTcpClient() . Когда приходит входящее соединение, то от TcpListener получаю TcpClient и вызываю в новом потоке свой метод Session. В этом методе происходит весь диалог между сервером и клиентом. После закрытия TCP сессии нужно выйти из метода Session и завершить поток. Все сделано на основе статей по простейшим серверам и по примерам из MSDN. Вот сам метод в котором идет общение внутри сессии (как пример, часть кода вырезано):
       void Sesion(object clientObj)
        {
            // начало потока для TCP сессии
 
            TcpClient client = (TcpClient)clientObj;
            NetworkStream stream = client.GetStream();
 
            Debug.WriteLine("Начадо сессии с IP " + IPAddress.Parse(((IPEndPoint)client.Client.RemoteEndPoint).Address.ToString()));
 
            while (client.Connected == true) // !!! Как определить, что сессия закрылась на стороне клиента?
            {
                if (client.Available > 0) // что-нибудь пришло?
                {
 
                    // читаем запрос
                    stream.Read(requestBuffer, 0, requestLenght);
 
                    // формируем ответ и отправляем
                    stream.Write(responseBuffer, 0, responseLenght);
                }
                else { Thread.Sleep(10); } // ждем данных
            }
 
            // Сюда должны попадать после закрытия сессии,
            // но никогда не попадаем.
 
            Debug.WriteLine("Завершение сессии"); 
            stream.Close();
 
            // завершение потока
        }
Проблема: нужен критерий, чтобы определить закрытие TCP сессии клиентом. Сейчас сделано
 while (client.Connected == true)
Но если клиент закрыл сессию, то client.Connected не становится false. Насколько понял, чтобы это свойство перешло в false после отключения клиента, дополнительно нужно отправить данные и не получить подтверждения от клиента. Но в моем случае сервер отправляет какие-либо данные только по запросу клиента. Сервер не может сам отправить данные для проверки сессии, т.к. это нарушит логику работы протокола. Мне нужен способ отправлять служебные TCP пакеты без данных или найти другой критерий проверки сессии.

Решение задачи: «Как определить, что TCP сессия была закрыта на другом конце»

textual
Листинг программы
if (client.Client.Poll(0, SelectMode.SelectRead))
{
    byte[] checkConn = new byte[1];
    if (client.Client.Receive(checkConn, SocketFlags.Peek) == 0)
    {
        // клиент отключился
        break;
    }
}

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

13   голосов , оценка 4.308 из 5
Похожие ответы