К сожалению, вызовы API sendto и recvfrom принципиально прерываются при использовании с сокетами, привязанными к «Any IP», потому что у них нет поля для локальной информации IP.
Так что вы можете с этим поделать?
- Вы можете угадать (например, на основе таблицы маршрутизации).
- Вы можете получить список локальных адресов и привязать отдельный сокет к каждому локальному адресу.
- Вы можете использовать более новые API, которые поддерживают эту информацию. Это состоит из двух частей: во-первых, вы должны использовать опцию relayvent socket (ip_recvif для IPv4, ipv6_recvif для IPv6), чтобы сообщить стеку, что вам нужна эта информация. Затем вы должны использовать другую функцию (recvmsg в linux и нескольких других unix-подобных системах, WSArecvmsg в windows) для получения пакета.
Ни один из этих вариантов не подходит. Гадание, очевидно, приведет к неправильным ответам. Связывание отдельных сокетов увеличивает сложность вашего программного обеспечения и вызывает проблемы, если список локальных адресов изменится, если ваша программа будет запущена. Более новые API-интерфейсы являются правильным техническим решением, но могут снизить переносимость (в частности, похоже, что WSArecvmsg недоступен в Windows XP) и могут потребовать изменения используемой вами библиотеки оболочки сокетов.
Правка выглядит так, как будто я ошибся, похоже, что документация MS вводит в заблуждение и что WSArecvmsg доступен в Windows XP. См https://stackoverflow.com/a/37334943/5083516