powered by simpleCommunicator - 2.0.58     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Виндавс издевается: Ошибка "Connection reset by peer" на UDP сокете
17 сообщений из 17, страница 1 из 1
Виндавс издевается: Ошибка "Connection reset by peer" на UDP сокете
    #39968137
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Виндавс7 слишком умный.

Получатель на UDP-порту 127.0.0.1:12345. Отправитель открывает случайный порт 127.0.0.1:0 и шлет на получателя.
Так все работает. Но если получателя нет, например не успел стартануть, то отправитель получает ошибку на recvfrom()
Код: plaintext
1.
2.
3.
int r = recvfrom(sock, (char*)msg->raw_ptr(), UDP_MAX_SIZE, 0, (SOCKADDR*) &msg->addr, &addr_size);
if(r <= 0) { // Ошибка сокета, остановка приема
	debug_log("%s: recv error %d", name_get(), WSAGetLastError());


WSAGetLastError() показывает 10054

https://docs.microsoft.com/en-us/windows/win32/winsock/windows-sockets-error-codes-2 WSAECONNRESET 10054

Connection reset by peer.
An existing connection was forcibly closed by the remote host. This normally results if the peer application on the remote host is suddenly stopped, the host is rebooted, the host or remote network interface is disabled, or the remote host uses a hard close (see setsockopt for more information on the SO_LINGER option on the remote socket). This error may also result if a connection was broken due to keep-alive activity detecting a failure while one or more operations are in progress. Operations that were in progress fail with WSAENETRESET. Subsequent operations fail with WSAECONNRESET.
Принцип работы: отправитель открывает порт и запускает отдельный поток для ожидания входящих, в том потоке recvfrom(). Затем происходит отправка нескольких пакетов и recvfrom() прекращает ожидание с ошибкой.

Нафига такая фича? Это же UDP, сейчас нет получателя, через секунду появился, а у меня поток приема уже завершился и больше ответов не ожидает.

Может кто знает как эту "продвинутость" отключить?

Код открытия порта
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
	bool open(int port = 0) {
		close();

		int err = udp_init();
		if(err != NO_ERROR) {
			release_log("%s: udp_init() error %d", name_get(), err);
			return false;
		}
	
		sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
		if (sock == INVALID_SOCKET) {
			release_log("%s: socket() error %d", name_get(), err);
			return false;
		}
		// Буферы приема и отправки
		int size = UDP_BUF_SIZE;
		err = setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char*)&size, sizeof(size));
		if (err != 0) {
			release_log("%s: setsockopt(SO_SNDBUF) error %d", name_get(), err);
			close();
			return false;
		}
		size *= 5;
		err = setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char*)&size, sizeof(size));
		if (err != 0) {
			release_log("%s: setsockopt(SO_RCVBUF) error %d", name_get(), err);
			close();
			return false;
		}

		// Установка запрета фрагментации пакетов
		int yes = IP_PMTUDISC_DO;
		err = setsockopt(sock, IPPROTO_IP, IP_DONTFRAGMENT, (char*)&yes, sizeof(yes));
		if (err != 0) {
			release_log("%s: setsockopt(IP_DONTFRAGMENT) error %d", name_get(), err);
			close();
			return false;
		}

		sockaddr_in addr_in;
		addr_in.sin_family = AF_INET;
		addr_in.sin_port = htons((uint16_t) port);
		#ifdef _DEBUG
		addr_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
		#else
		addr_in.sin_addr.s_addr = htonl(INADDR_ANY);
		#endif

		err = bind(sock, (SOCKADDR*)&addr_in, (socklen_t)sizeof(sockaddr_in));
		if (err != 0) {
			release_log("%s: bind() error %d", name_get(), err);
			close();
			return false;
		}
		
		th_recv = std::thread(recv_thread, this); // Поток с recvfrom()

		return true;
	}



PS sendto() никаких ошибок не выдает.
...
Рейтинг: 0 / 0
Виндавс издевается: Ошибка "Connection reset by peer" на UDP сокете
    #39968151
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дело, скорее всего, в том, что при получении пакета, которого никто не ждёт, IP-стек отправляет ICMP-ответ "нехрен сюда долбиться" ( Port Unreachable ).
Интеллект винды тут ни при делах - это (штатная) ситуация, которую надо (как-то) обрабатывать.
...
Рейтинг: 0 / 0
Виндавс издевается: Ошибка "Connection reset by peer" на UDP сокете
    #39968175
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T
Может кто знает как эту "продвинутость" отключить?

Отключать не надо. Просто после такой ошибки еще раз повторить отправку/получение
...
Рейтинг: 0 / 0
Виндавс издевается: Ошибка "Connection reset by peer" на UDP сокете
    #39968180
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Имеет смысл повторять с экспоненциальным таймаутом.
Или использовать шаблон cirquit-breaker если таковых потоков будет
несколько которые имеют интерес писать в этот UDP-port.
...
Рейтинг: 0 / 0
Виндавс издевается: Ошибка "Connection reset by peer" на UDP сокете
    #39968184
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
Имеет смысл повторять с экспоненциальным таймаутом.
Или использовать шаблон cirquit-breaker если таковых потоков будет
несколько которые имеют интерес писать в этот UDP-port.

А зачем экспоненциальный таймаут?
...
Рейтинг: 0 / 0
Виндавс издевается: Ошибка "Connection reset by peer" на UDP сокете
    #39968187
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добавил проверку этой ошибки
Код: plaintext
1.
if (WSAGetLastError() == 10054) continue;


срабатывает ровно столько раз - сколько отправлено UDP-пакетов, т.е. после каждого вызова sendto().

При отправке на другой комп этой ошибки не происходит, т.е. как-то ее обрабатывать нет смысла, только игнорить, чтобы при отладке не мешала.
...
Рейтинг: 0 / 0
Виндавс издевается: Ошибка "Connection reset by peer" на UDP сокете
    #39968188
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T
При отправке на другой комп этой ошибки не происходит
... только потому, что этот "другой комп" работает в режиме "невидимки".
...
Рейтинг: 0 / 0
Виндавс издевается: Ошибка "Connection reset by peer" на UDP сокете
    #39968192
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. Sidorov
Dima T
При отправке на другой комп этой ошибки не происходит
... только потому, что этот "другой комп" работает в режиме "невидимки".

Нет, комп пингуется, в его расшаренные папки захожу, браэндмауэр в режиме "сеть предприятия". Стандартные настройки.
...
Рейтинг: 0 / 0
Виндавс издевается: Ошибка "Connection reset by peer" на UDP сокете
    #39968195
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav
mayton
Имеет смысл повторять с экспоненциальным таймаутом.
Или использовать шаблон cirquit-breaker если таковых потоков будет
несколько которые имеют интерес писать в этот UDP-port.

А зачем экспоненциальный таймаут?

Я сейчас ищу какой-то ответ. Но все ответы очень банальные.

Вобщем. Так принято. Чтоб не перегружать сеть безсмысленными пробами.
...
Рейтинг: 0 / 0
Виндавс издевается: Ошибка "Connection reset by peer" на UDP сокете
    #39968198
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По умолчанию, штатный виндовый файервол разрешает далеко не все ICMP-коды. "Echo request/reply" (пинг) - да, с остальным будут варианты.
...
Рейтинг: 0 / 0
Виндавс издевается: Ошибка "Connection reset by peer" на UDP сокете
    #39968202
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
Чтоб не перегружать сеть безсмысленными пробами
... сообщить о возможной проблеме.
"Перегружать" или не "перегружать" - зависит от действий получателя и реакции отправителя.
...
Рейтинг: 0 / 0
Виндавс издевается: Ошибка "Connection reset by peer" на UDP сокете
    #39968211
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
petrav
пропущено...

А зачем экспоненциальный таймаут?

Я сейчас ищу какой-то ответ. Но все ответы очень банальные.

Вобщем. Так принято. Чтоб не перегружать сеть безсмысленными пробами.

Это тут лишнее, т.к. управление потоком вынесено на уровень выше, не будет ответов - отправка прекратиться. В данном слое требуется только отправить/принять.
...
Рейтинг: 0 / 0
Виндавс издевается: Ошибка "Connection reset by peer" на UDP сокете
    #39968212
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это корнями уходит в теорию управления.

Последний раз мы использовали этот алгоритм явно при работе с загрузкой данных в S3Bucket.
У него было определённое поведение когда в ответ на IOException (с кодом
HTTP-429 или что-то подобное), самое правильное что мы могли сделать это "подождать"
с ростом пауз. И с джиттером.
...
Рейтинг: 0 / 0
Виндавс издевается: Ошибка "Connection reset by peer" на UDP сокете
    #39968218
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T https://docs.microsoft.com/en-us/windows/win32/winsock/windows-sockets-error-codes-2
А теперь открываем доку посвежее:
https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-recvfrom
MSDNWSAECONNRESET

The virtual circuit was reset by the remote side executing a hard or abortive close. The
application should close the socket; it is no longer usable. On a UDP-datagram socket
this error indicates a previous send operation resulted in an ICMP Port Unreachable
message.

Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Виндавс издевается: Ошибка "Connection reset by peer" на UDP сокете
    #39968236
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. Sidorov
По умолчанию, штатный виндовый файервол разрешает далеко не все ICMP-коды. "Echo request/reply" (пинг) - да, с остальным будут варианты.

Похоже что так оно и есть. Отключил брандмауэры на обоих компах - получил эту ошибку по сети.
...
Рейтинг: 0 / 0
Виндавс издевается: Ошибка "Connection reset by peer" на UDP сокете
    #39968503
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Отключать наверное не стоило.

Просто разрешить ICMP.
...
Рейтинг: 0 / 0
Виндавс издевается: Ошибка "Connection reset by peer" на UDP сокете
    #39968641
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
Отключать наверное не стоило.

Просто разрешить ICMP.

Я временно, для теста. А так нет смыла под софт менять настройки ОС, не везде дадут это сделать.
...
Рейтинг: 0 / 0
17 сообщений из 17, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Виндавс издевается: Ошибка "Connection reset by peer" на UDP сокете
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]