Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Виндавс издевается: Ошибка "Connection reset by peer" на UDP сокете / 17 сообщений из 17, страница 1 из 1
11.06.2020, 10:31
    #39968137
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Виндавс издевается: Ошибка "Connection reset by peer" на UDP сокете
Виндавс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
11.06.2020, 11:19
    #39968151
Basil A. Sidorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Виндавс издевается: Ошибка "Connection reset by peer" на UDP сокете
Дело, скорее всего, в том, что при получении пакета, которого никто не ждёт, IP-стек отправляет ICMP-ответ "нехрен сюда долбиться" ( Port Unreachable ).
Интеллект винды тут ни при делах - это (штатная) ситуация, которую надо (как-то) обрабатывать.
...
Рейтинг: 0 / 0
11.06.2020, 12:02
    #39968175
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Виндавс издевается: Ошибка "Connection reset by peer" на UDP сокете
Dima T
Может кто знает как эту "продвинутость" отключить?

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

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


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

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

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

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

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

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

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

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

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

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

Последний раз мы использовали этот алгоритм явно при работе с загрузкой данных в S3Bucket.
У него было определённое поведение когда в ответ на IOException (с кодом
HTTP-429 или что-то подобное), самое правильное что мы могли сделать это "подождать"
с ростом пауз. И с джиттером.
...
Рейтинг: 0 / 0
11.06.2020, 13:15
    #39968218
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Виндавс издевается: Ошибка "Connection reset by peer" на UDP сокете
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
11.06.2020, 13:58
    #39968236
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Виндавс издевается: Ошибка "Connection reset by peer" на UDP сокете
Basil A. Sidorov
По умолчанию, штатный виндовый файервол разрешает далеко не все ICMP-коды. "Echo request/reply" (пинг) - да, с остальным будут варианты.

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

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

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

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


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