Рекомендация: держать TCP / IP-соединение открытым или закрывать после каждой передачи? - PullRequest
11 голосов
/ 17 февраля 2011

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

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

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

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

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

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

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

Ответы [ 7 ]

10 голосов
/ 18 февраля 2011

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

8 голосов
/ 17 февраля 2011

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

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

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

У меня даже были некоторые проблемы с подключением из-за большого количества параллельных запросов: мне не хватало портов на моем сервере!

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

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

Короче: если вы можетеоставьте ваши клиентские подключения живыми в течение нескольких минут.

6 голосов
/ 17 февраля 2011

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

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

/ twocents

3 голосов
/ 18 февраля 2011

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

3 голосов
/ 17 февраля 2011

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

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

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

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

0 голосов
/ 02 февраля 2018

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

0 голосов
/ 28 мая 2017

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

...