Не удается назначить запрашиваемый адрес - возможные причины? - PullRequest
19 голосов
/ 04 октября 2011

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

Из проверки журналов я обнаружил, что ведомое устройство может только отправить одно обновление состояния на сервер, а затем никогда не может отправить другое обновление, всегда терпя неудачу при вызове connect () "Невозможно назначитьзапрашиваемый адрес (99).

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

Чтобы уточнить, вот как я подключаюсь:

struct sockaddr *sa; // parameter
size_t           sa_size; //parameter
int              i = 1;
int              stream;

stream = socket(AF_INET,SOCK_STREAM,0);
setsockopt(stream,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(i));
bindresvport(stream,NULL);
connect(stream,sa,sa_size);

Этокод находится в функции для получения соединения с другим сервером, и сбой при любом из этих 4 вызовов приводит к сбою функции.

Ответы [ 4 ]

9 голосов
/ 04 октября 2011

Может быть, SO_REUSEADDR здесь поможет? http://www.unixguide.net/network/socketfaq/4.5.shtml

6 голосов
/ 05 октября 2011

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

РЕДАКТИРОВАТЬ: если быть точным, то проблемы с обработкой наших сетевых коммуникаций заключались в том, что эти обновления статуса будут постоянно пересылаться в случае первого сбоя. Это был лишь вопрос времени, когда каждый распределенный ведомый сервер попытался отправить свое обновление статуса в одно и то же время, что перенасыщало нашу сеть.

5 голосов
/ 04 октября 2011

это просто выстрел в темноте: когда вы сначала вызываете connect без привязки, система выделяет ваш локальный порт, и если у вас есть несколько потоков, подключающихся и отключающихся, он может попытаться выделить уже используемый порт. исходный файл ядра inet_connection_sock.c намекает на это условие. просто в качестве эксперимента попробуйте сначала выполнить связывание с локальным портом, убедившись, что каждое связывание / соединение использует другой номер локального порта.

0 голосов
/ 12 ноября 2012
sysctl -w net.ipv4.tcp_timestamps=1
sysctl -w net.ipv4.tcp_tw_recycle=1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...