Подтвердить что ты не робот

Невозможно назначить запрошенный адрес - возможные причины?

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

При проверке журналов я обнаружил, что ведомое устройство может отправлять только одно обновление статуса на сервер, а затем никогда не может отправлять другое обновление, всегда не выполняющее вызов для соединения() "Невозможно назначить запрошенный адрес ( 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 вызовов приводит к сбою функции.

4b9b3361

Ответ 2

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

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

Ответ 3

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

Ответ 4

sysctl -w net.ipv4.tcp_timestamps=1
sysctl -w net.ipv4.tcp_tw_recycle=1