Задание параметра времени ожидания с помощью setsockopt () приводит к последующей ошибке прослушивания

Сейчас я пытаюсь указать параметры с setsockopt() используя следующий код:

// bind socket
// Use setsockopt() function to make sure the port is not in use
int yes = 1;
setsockopt(TCPSocket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
setsockopt(TCPSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval));
status = bind(TCPSocket, host_info_list->ai_addr, host_info_list->ai_addrlen);
if (status == -1)  std::cout << "bind error" << std::endl ;

// listen for connections
status =  listen(TCPSocket, 5);
if (status == -1)  std::cout << "listen error" << std::endl ;

int new_sd;
struct sockaddr_storage their_addr;
socklen_t addr_size = sizeof(their_addr);
new_sd = accept(TCPSocket, (struct sockaddr *)&their_addr, &addr_size);
if (new_sd == -1) std::cout << "listen error" << std::endl ;

Заметка tv это уже указанное время.

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

Я не беру кредит на указанный код; он модифицирован из кода, представленного в руководстве здесь: http://codebase.eu/tutorial/linux-socket-programming-c/

0

Решение

Если вы видите диаграмму состояния TCP как этот Вы видите, что есть состояние под названием TIME_WAIT при активном закрытии сокета. Это состояние может занять некоторое время, прежде чем оно закончится, до четырех минут в зависимости от RFC793.

Пока розетка находится в TIME_WAIT Вы не можете привязать к интерфейсу, используя ту же пару адрес-порт, что и сокет, который находится в состоянии ожидания. Настройка SO_REUSEADDR флаг om socket позволяет другим сокетам связываться с адресом, когда текущий сокет (с установленным флагом) находится в TIME_WAIT государство.

SO_REUSEADDR Опция наиболее полезна для серверных (пассивных, прослушивающих) сокетов.


Что касается вашей проблемы, после каждого звонка setsockopt проверьте, что он возвращает, и если это -1 тогда вы проверяете errno чтобы увидеть, что пошло не так. Ты можешь использовать perror или же strerror распечатать или получить печатаемую строку для ошибки, например

if (setsockopt(TCPSocket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) < 0)
{
std::cerr << "Error setting the SO_REUSEADDR: " << strerror(errno) << '\n';
// Do something appropriate
}
2

Другие решения

Решение Йоахима отлично ответило на мой начальный вопрос и объяснило setsockopt (). Чтобы ответить на мой собственный вопрос после того, как выяснилось, что проблема была еще ниже в коде, тайм-аут влияет на способность сервера прослушивать порт. Скажем, время ожидания составляет всего 10 мс, сервер должен быть запущен, затем клиент, и за это время должно быть установлено соединение. Это не происходило в моем случае, поэтому возникла ошибка.

0

По вопросам рекламы [email protected]