2011-02-17 2 views
10

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

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

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

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

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

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

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

+3

Накладные расходы на создание нового TCP-соединения - это, в основном, несколько раундов. И это довольно быстро в локальной сети. Поэтому я закрою соединение через несколько секунд, не используя его. – CodesInChaos

+3

Но я бы написал его простым способом (скорее всего, мгновенным закрытием), а затем проверить, удовлетворяет ли производительность. – CodesInChaos

+4

См. Мой ответ на этот вопрос: http://stackoverflow.com/questions/4872800/socket-open-and-close-on-1-sec-or-to-hold-open/4873002#4873002 –

ответ

8

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

+0

Remy, хорошая работа на Indy за последние несколько лет ;-) Я широко использую компоненты TCP Indy, и я имею в виду широко, как неотъемлемую часть моей распределенной прикладной структуры. Вы можете взглянуть на него. – Misha

6

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

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

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

/twocents

8

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

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

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

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

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

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

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

3

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

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

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

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

3

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

0

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

+0

Хотя пул потоков ОС, я бы предпочел увидеть, что реализовано на серверах Indy (а не на клиентском потоке), то, что вы заявляете здесь, неверно - см., Например, https://blogs.msdn.microsoft.com/oldnewthing/20050729-14/?p=34773 – Victoria

0

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

 Смежные вопросы

  • Нет связанных вопросов^_^