Как ждать, пока ваше TCP-сообщение не будет подтверждено - PullRequest
3 голосов
/ 03 июля 2010

Справочная информация:

У нас есть клиент-серверное приложение, которое использует постоянное соединение с сервером.

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

К сожалению, старое соединение может устареть.

Есть ли способ ожидания результата отправки сообщения на системном уровне [ACK или ошибка]?

Ожидание чтения, а затем получение конца потока вызывает путаницу.

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

Ответы [ 3 ]

2 голосов
/ 03 июля 2010

К сожалению, старое соединение может устареть.

В этом случае вы получите исключение при записи в него, в конце концов.

Есть лиспособ ожидания результата отправки сообщения на системном уровне [ACK или ошибка]?

Ожидание чтения и затем получение концаПоток вызывает путаницу.

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

Я знаю, что сообщение может быть разбито на пакеты.1022 *

Совершенно не имеет значения.Вы не имеете никакого контроля над этим или какой-либо видимости этого либо.То, что вы получите, - это поток байтов, прерванный EOS, или исключение.

Для моих целей было бы одинаково хорошо узнать, была ли какая-либо часть сообщения взломана или вся она была.

Нет, не будет.ACK означает только то, что он достиг такого же стека TCP / IP партнера.Что ваше приложение интересует, так это то, попало ли оно в одноранговое приложение, и только одноранговое приложение может сказать вам это через ACK уровня протокола приложения.TCP / IP ACK здесь не помогут.

Интересная проблема здесь - устаревшее соединение.

И это довольно тривиальная проблема.Вы можете обнаружить это в коде, и вы можете иметь дело с этим также.Поставщики баз данных занимались этим десятилетиями.Не ракетостроение и ничего, что требует знания TCP ACK.

0 голосов
/ 03 июля 2010

Сам стек TCP вряд ли своевременно сообщит вам, если соединение больше не жизнеспособно (если оно не локально разорвано и ОС не может сообщать о локальных сбоях в стек).Из-за тайм-аутов повторной передачи (см. здесь ) и того, что может потребоваться «довольно много времени», прежде чем запись выдаст ошибку, указывающую на разрыв соединения.Это, конечно, по замыслу, просто дизайн противоречит тому, что вы хотите сделать.

Вы можете попробовать использовать протокол TCP для поддержки активности, но ИМХО, это действительно не стоит усилий, и вы 'Было бы лучше реализовать некоторую форму ACK уровня приложения, если это возможно, чтобы вы могли заставить свой протокол уровня приложения отправлять ответ, как только он получит некоторые данные от вас.Если вы не можете сделать это, и ваш запрос вызывает ответ с другого конца соединения, тогда вы можете просто установить таймер, основываясь на том, как долго вы готовы ждать ответа, прежде чем предположить, что соединение разорвано.Когда таймер истекает, вы закрываете свое соединение и устанавливаете новое.

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

Наконец,если соединение разрывается из-за неактивности, то, возможно, вы могли бы добавить пинг уровня приложения к вашему протоколу, который можно настроить так, чтобы он отправлял сообщения время от времени, чтобы: а) гарантировать, что соединение живо, и б) мешать маршрутизаторам или брандмауэрам думатьсоединение разорвано.

0 голосов
/ 03 июля 2010

На уровне, на котором вы обрабатываете связь TCP, вам не нужно беспокоиться о ACK. Это работа слоя 3 и ниже. Для вашего протокола всегда делайте запросы команд / ответов. Ответ должен быть там независимо от того, был ли успех или ошибка. Интерпретация отсутствия ответа как успеха опасна, так как разрыв связи может привести к тому же эффекту.

Я не знаю точно, что вы подразумеваете под устаревшими. Поскольку TCP является протоколом, ориентированным на соединение, соединение существует или нет. Поэтому я не совсем понимаю, какие у вас проблемы: если вы потеряете соединение, вам придется приложить усилия для создания нового.

...