КПК теряет TCP-соединение с ServerSocket в режиме ожидания - PullRequest
1 голос
/ 02 июля 2010

Я использую Java / TCP / IP-сервер, используя ServerSocket для приема сообщений от клиентов через сетевые сокеты.

Работает нормально, за исключением клиентов на КПК (сканер штрих-кода WIFI). Если у меня есть соединение между сервером и кпк - и кпк через некоторое время простаивает (в режиме ожидания) - тогда будут проблемы с соединением. Когда кпк снова просыпается, я могу наблюдать на мониторе tcp, что второе соединение с другим портом установлено, но старый также остается установленным:

localhost: 2000 remotehost: 4899 ESTABLISHED (первое соединение)

localhost: 2000 remotehost: 4890 ESTABLISHED (соединение после пробуждения)

И теперь связь не работает, так как клиент теперь использует новое соединение, но сервер все еще слушает старое, поэтому сервер не получает сообщения. Но когда сервер отправляет сообщение клиенту, он осознает проблему (получает SocketException: сброс соединения. Затем сервер использует новое соединение, и все сообщения, которые были тем временем отправлены клиентом, будут получены на один удар!

Итак, я сначала осознаю проблемы с сетью, когда сервер пытается отправить сообщение - но в то же время нет никаких исключений или чего-либо еще. Как правильно отреагировать на эту проблему - чтобы новое соединение использовалось, как только оно установлено (а старое закрыто)?

Ответы [ 2 ]

1 голос
/ 02 июля 2010

Из вашего описания я предполагаю, что сервер структурирован так:

server_loop
{
    client_socket = server_socket.accept()
    TalkToClientUntilConnectionCloses(client_socket)
}

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

server_loop
{
    client_socket = server_socket.accept()
    StartClientThread(client_socket)
}

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

1 голос
/ 02 июля 2010

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

Рассматривали ли вы установку тайм-аута для соединения на сокете на стороне сервера (сокет соединения, а не сокет сервера), чтобы можно было закрыть / сбросить его через определенный период? Возможно, после истечения срока действия SO_TIMEOUT на сокете вы можете проверить его с помощью команды echo / keepalive, чтобы убедиться, что соединение все еще исправно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...