используя тот же tcpclient для чтения / записи и поддерживая его - PullRequest
4 голосов
/ 01 марта 2012

У меня следующая ситуация:
Клиент -> Маршрутизатор -> Интернет -> Выделенный сервер

Клиент: При запуске подключается к серверу и сохраняет соединение открытым.Изредка получает уведомления от сервера о том, что файлы изменены.Запускает процесс синхронизации, а затем уведомляет сервер, если это было успешно.Может время от времени терять соединение, поэтому необходимо установить новое соединение.

Сервер (интернет): Содержит файлы, которые иногда изменяются.Принимает входящих клиентов и сохраняет объект tcpclient для этого клиента.Он никогда не может соединиться напрямую с клиентом, потому что клиент сидит за несколькими маршрутизаторами;Вот почему связь должна быть открытой.Уведомляет клиента (ов), когда изменение сделано.А также проверяет для каждого клиента сообщение об успешной синхронизации.

Вопросы:

  1. Как эффективно поддерживать соединение открытымна стороне клиента и сервера?

  2. Что происходит, когда клиент хочет уведомить сервер об успешном процессе синхронизации, но в то же время сервер уведомляет об этомклиент для нового обновления ..?

  3. Является ли хорошей практикой просто создать Tcpclient (на стороне клиента) и сохранить этот объект на протяжении всей программы?А когда какая-то сетевая операция завершилась неудачно, попробуйте снова подключиться к этому объекту tcpclient?

Я провел много исследований, но не смог найти то, что продолжает использовать тот же tcpclient ..

Кстати: это новая тема, основанная на моем предыдущем посте, где было предложено это решение (повторно использовать tcpclient) ( пакет udp не проходит через )

Приветствует Daan & спасибо взаранее к вашему вниманию

Ответы [ 3 ]

6 голосов
/ 01 марта 2012

Как эффективно сохранить соединение открытым на стороне клиента и сервера?

TCP отправляет может отправлять сообщения в режиме реального времени по умолчанию , если вы активируете SO_KEEPALIVE. Но может быть хорошей идеей отправлять собственные сообщения поддержки активности (для предотвращения отключения неактивного соединения в маршрутизаторах и т. Д.)

Что происходит, когда клиент хочет уведомить сервер о том, что процесс синхронизации прошел успешно, но в то же время сервер уведомляет клиента о новом обновлении ..?

Создайте свой протокол так, чтобы он имел идентификатор запроса и мог различаться в уведомлениях и ответах.

Создайте свой API-интерфейс синхронным, но используйте асинхронную обработку сокетов.

Является ли хорошей практикой просто создавать Tcpclient (на стороне клиента) и сохранять этот объект на протяжении всей программы? А когда какая-то сетевая операция не удалась, попробуйте снова подключиться к этому объекту tcpclient?

Вы уверены, что возможно снова подключиться к тому же клиенту? IIRC это невозможно с Socket и то же самое должно применяться к TcpClient

Я бы использовал тот же клиент, если он не отключен.

3 голосов
/ 01 марта 2012
  1. Чтобы убедиться, что соединение остается открытым и что между клиентом и сервером нет сетевых сбоев, вы можете добавить в протокол два сообщения: Keep-alive и keep-alive-reply.Либо клиент, либо сервер (это зависит от вас) отправляют сообщение проверки активности через регулярные промежутки времени (возможно, раз в минуту), а другая сторона отвечает сообщением подтверждения активности.Если отправитель сообщения keep-alive не получил ответа, когда пришло время отправить следующее сообщение keep-alive, то соединение можно считать устаревшим и закрыть соединение.Другой конец, тот, кто отправляет ответы, нуждается в таймере.Если запрос подтверждения активности не был получен в назначенное время, он должен закрыть соединение.
  2. Клиент просто пропускает уведомления из очереди сервера и обрабатывает их, когда может.Либо вы увеличиваете приемный буфер в клиенте (setsockopt и SO_RCVBUF), либо сохраняете свою очередь.Чтобы отслеживать, какое сообщение «sync-done» подходит к какому сообщению «do-sync», вы должны добавить какой-либо идентификатор сообщения в ваши сообщения.Это может быть простое целочисленное значение, которое начинается с нуля, а затем сервер увеличивает его на единицу для каждого сообщения «do-sync».
  3. Пока у вас есть работающее соединение, сохраняйте объект соединения.Когда придет время для повторного подключения, я создам новый объект подключения, просто чтобы быть в безопасности.Но это может сработать с повторным использованием старого, я недостаточно хорошо знаю C # и библиотеку .NET.
0 голосов
/ 01 марта 2012

Хейуп Даан. Эта проблема уже была решена в последнем коммите networkComms.net . Он поддерживает соединение, отправляя один байт каждые пару секунд, если обнаруживает, что другой трафик не отправляется. Если вы посмотрите на эту библиотеку сетевых коммуникаций с открытым исходным кодом C #, начиная с 11-строчного примера здесь , вы можете начать работать немного быстрее, чем создавать все с нуля.

...