Ошибка повторного подключения сокета - PullRequest
0 голосов
/ 22 октября 2010

Системный фон: в основном это клиент-серверное приложение.Сервер - это встроенное устройство, а Клиент - это приложение для Windows, разработанное на C ++.

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

  1. Аварийное завершение на удаленном конце
  2. Блокировка порта

Требуются некоторые советы о том, как правильно очистить сокет или отключить, чтобы переподключение происходило правильно,Другие альтернативные решения?

Спасибо, Хуссейн

Ответы [ 3 ]

2 голосов
/ 22 октября 2010

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

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

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

Одна вещь, которую вы, возможно, захотите проверить, это то, что вы не поражены отсутствием возможности повторного использования адресов.Иногда, когда сокет закрывается, его нельзя сразу же повторно использовать для попытки повторного подключения, поскольку на одном или другом конце все еще сохраняется остаточная активность.Вы можете обойти это (основываясь на моем опыте работы с Windows / Winsock), экспериментируя с SO_REUSEADDR и SO_LINGER на своих сокетах.тем не менее, мой первый акцент в вашем случае будет заключаться в том, чтобы код сокета на клиенте и сервере правильно обрабатывал все ошибки и основные случаи, прежде чем беспокоиться об этом.

1 голос
/ 22 октября 2010

Распространенной проблемой является то, что когда соединение сбрасывается, оно остается открытым ОС в состоянии TIME_WAIT.Если вы хотите перезапустить сокет сервера, он не сможет открыть этот же порт напрямую, потому что он все еще присутствует в ОС.Чтобы избежать этого, вам нужно установить параметр SO_REUSEADDR, чтобы ОС позволяла вам повторно использовать порт, если он находится в состоянии TIME_WAIT для сокета сервера.

Пример:

int optval=1;
// set SO_REUSEADDR on a socket to true (1):
setsockopt(s1, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval);
0 голосов
/ 22 октября 2010

Я испытываю нечто подобное с зашифрованными соединениями.Я полагаю, что в моем случае это потому, что клиент разорвал соединение и переподключился менее чем за 4 минуты FIN_WAIT.Исходное соединение перезагружено (ОС), и сервер не видит выпадение.Аутентификация SSL теряется, когда клиент теряет соединение, поэтому клиент пытается повторно пройти аутентификацию.Это то, что серверы считают серединой разговора.Затем сервер зависает на клиенте.Я думаю, что серверный ssl-код считает, что это человек в середине атаки, или он просто сбит с толку и закрывает соединение.

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