2015-04-07 3 views
0

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

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

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

Редактировать: - Я нашел это, проходя через различные статьи.

На вопрос об использовании SO_LINGER отправить RST на близко, чтобы избежать состояния TIME_WAIT: У меня возникли некоторые проблемы с серверами доступа маршрутизатора (имена удержаны, чтобы защитить виновных), которые имеют проблемы, касающиеся бэк- к модеме, подключенному к определенному каналу. То, что они делают, - это отпустить соединение, принять другой вызов, попытаться подключиться к известному сокету на хосте, и хост отказывается от соединения, потому что в состоянии TIME_WAIT есть соединение с известным сокетом. (Книга Стивенса TCP Illustrated, В томе 1 более подробно обсуждается эта проблема.) Во избежание отказа в подключении мне пришлось установить опцию «reset-on-close» на сервере, когда сервер инициирует отключение.

Ссылка на источник: - http://developerweb.net/viewtopic.php?id=2941

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

+0

Не используйте форматирование кода для текста, который не является кодом. – EJP

+0

Пожалуйста, не используйте форматирование кода для текста, который не является кодом. – EJP

ответ

0

Перед перезагрузкой сервера необходимо закрыть сокет, связанный с этим портом!

http://www.gnu.org/software/libc/manual/html_node/Closing-a-Socket.html

Кроме того, есть время тайм-аута, который я думаю, 4 минуты, так что если вы создали сокет TCP и закрыть его, вы, возможно, придется подождать 4 минуты, пока она не закроется.

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

+0

netstat показывает, что клиентское соединение все еще существует, но я не уверен, что его соединение с клиентской стороны или из-за неправильного способа выхода сервера без закрытия сокета. Проблема в том, когда клиентский процесс закрыт, а сервер снова может публиковать на этих портах. – Invictus

+0

Как вы закрываете сокет на сервере? Что происходит, я полагаю, что серверный сокет не отправляет тесное взаимодействие TCP-соединения, а ваш клиент все еще потребляет этот сокет ИЛИ, сокет остается открытым, так как вы не закрываете его на сервере (и его застрял в процессе зомби). Обязательно вызовите shutdown со значением 2 в том, как, а не закрывать, чтобы полностью отключить сокет (не дожидаясь передачи). http://www.gnu.org/software/libc/manual/html_node/Closing-a-Socket.html – Magn3s1um

+0

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

1

Установите SO_REUSEADDR опцию на сокет сервера, прежде чем связать его и вызвать listen().

EDIT предложению возиться с SO_LINGER вариантом является бесполезной и опасной для ваших данных в полете. Просто используйте SO_RESUSEADDR.

+0

Отредактировал мой вопрос, давая точный сценарий, с которым я столкнулся. Будет ли ваш ответ по-прежнему справедливым? – Invictus

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