Повторно подключите TCPClient после прерывания - PullRequest
3 голосов
/ 06 мая 2011

У меня есть несколько экземпляров клиентского приложения, подключающегося к основному приложению через Интернет через TcpClient.(Оба написаны мной).Таким образом, соединение устанавливается следующим образом:

TcpClient.Connect (ip, port)

Теперь я хочу, чтобы это обрабатывало различные типы событий отключения:

  1. Главное приложение (сервер) или клиентское приложение теряют подключение к Интернету.

    • При возобновлении соединения связь кажется потерянной, но когда я пытаюсь восстановить соединение, я получаю сообщение: "Был сделан запрос соединения на уже подключенном сокете"
    • Так что мне нужно закрыть и перезапустить клиентское приложение.
  2. Основное приложение (сервер) закрыто и перезапущено.

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

Итак, что мне нужно сделать?Нужно ли создавать новый TcpClient в клиентских приложениях всякий раз, когда происходит такое прерывание?Я этого не пробовал, так что не знаю, плохое ли это решение?

Ответы [ 2 ]

6 голосов
/ 06 мая 2011

нужно ли создавать экземпляр нового TcpClient в клиентских приложениях, когда такое прерывание происходит?

Да. Если соединение, представленное TcpClient, разорвано, вы не можете использовать этот объект для дальнейшего общения и не можете подключить его снова. Создайте новый объект TcpClient.

Ваша проблема, вероятно, в том, что шлюз NAT прерывает ваше TCP-соединение, поэтому между вашим сервером <-> клиент ничего не может пройти, если все, что делает ваш клиент, читает из соединения, он не обнаружит этот случай, и он считает, что соединение все еще открыто.

1 голос
/ 06 мая 2011

Обычно я раньше решал эту проблему с помощью потоков. Я создал управляющий поток, который просматривает и выполняет административные операции, такие как: проверка соединения, проверка последнего пользовательского ввода, проверка запроса на отключение сервера и т. Д. Когда это было сделано, он спал в течение полсекунды и делал все заново.

У меня тогда был отдельный поток Socket, который был создан и просто обслуживал сетевой сокет. После этого соединение будет открываться и многократно проверяться на предмет входящих сообщений от того, к кому оно подключено. Если он найдет сообщение, он обработает его и сохранит в коллекции изменчивых объектов для использования потоком управления. Если что-то случится с соединением, оно автоматически попытается разрешить, а если не сможет, то перейдет в «мертвое» состояние. Поток управления на своей следующей итерации будет очищать мертвые потоки сокетов и создавать новые при необходимости.

Отладка была кошмаром, но она была на удивление стабильной после устранения ошибок. В одном случае он успешно работал более года с десятками тысяч подключений и сотнями одновременных подключений без необходимости перезапуска или технического обслуживания.

...