Передовая практика: сохранить соединение TCP/IP открытым или закрыть его после каждой передачи?

В моем сервере-приложении используется TIdTCPServer, несколько клиентских приложений используют TIdTCPClients для подключения к серверу (все компьютеры находятся в одной локальной сети).

Некоторым клиентам приходится обращаться к серверу каждые пару минут, другие - раз в секунду, а один - примерно 20 раз в секунду.

Если я поддерживаю соединение между клиентом и сервером, я сохраню повторное подключение, но должен проверить, не потеряно ли соединение.

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

Каков наилучший способ сделать это?

На какой частоте передачи данных я должен держать соединение открытым вообще?

Каковы другие преимущества/недостатки для обоих сценариев?

Ответ 1

Я бы предложил сочетание этих двух. Когда новое соединение открывается, запустите для него таймер простоя. Всякий раз, когда данные обмениваются, reset таймер. Если таймер истечет, закройте соединение. Если соединение было закрыто, когда необходимо отправить данные, откройте новое соединение и повторите попытку. Таким образом, менее часто используемые соединения могут закрываться периодически, в то время как более часто используемые соединения могут оставаться открытыми.

Ответ 2

Два цента из эксперимента...

В моем первом клиентском/серверном приложении TCP/IP было использовано новое соединение и новый поток для каждого запроса... лет назад...

Затем я обнаружил (используя ProcessExplorer), что он потребляет некоторые сетевые ресурсы, потому что все закрытые соединения действительно не уничтожены, но остаются в определенном состоянии в течение некоторого времени. Было создано много потоков...

У меня даже были проблемы с соединением с множеством совпадающих запросов: у меня не было достаточно портов на моем сервере!

Итак Я переписал его, следуя схеме HTTP/1.1 и KeepAlive. Это намного эффективнее, используйте небольшое количество потоков, а ProcessExplorer - мой новый сервер. И я больше не выхожу из порта.:)

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

Вкратце: если вы можете, поддерживайте свои клиентские соединения в течение нескольких минут.

Ответ 3

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

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

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

/twocents

Ответ 4

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

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

Я реализовал систему чата для проекта, в котором ~ 50 человек (число растет с каждым 2 месяцами) всегда подключены, и помимо чата он также включает передачу данных, манипулирование базами данных с использованием определенных команд и т.д. Моя реализация поддерживает соединение с сервером от запуска приложения до закрытия приложения, никаких проблем до сих пор, однако, если соединение потеряно по какой-либо причине, оно автоматически восстанавливается, и все продолжается безупречно.

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

Ответ 5

Если вы не масштабируете сотни сотен одновременных соединений, я бы определенно оставил их открытыми - это, безусловно, лучший из двух вариантов. После того, как вы масштабируете сотни и тысячи одновременных соединений, вам, возможно, придется отказаться и снова подключиться. Я сконструировал всю свою структуру вокруг этого (http://www.csinnovations.com/framework_overview.htm), поскольку он позволяет мне "нажимать" данные клиенту с сервера, когда это требуется. Вам нужно написать справедливый бит кода, чтобы убедиться, что соединение работает и работает (выпадение сети, таймерные пинги и т.д.), Но если вы сделаете это в своей "фреймворке", тогда ваш код приложения можно записать в таком что вы можете предположить, что соединение всегда "вверх".

Ответ 6

Проблема - это ограничение потоков для каждого приложения, около 1400 потоков. Таким образом, максимум 1300 клиентов подключены одновременно + -.

Ответ 7

При закрытии соединений в качестве клиента порт, который вы использовали, будет недоступен некоторое время. Таким образом, при большом объеме youre использует множество разных портов. Для чего-либо повторяющегося id держите его открытым.