Как зайти в Даркнет?!
25th January, 01:11
8
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
898
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
951
0
Очень долго работает Update запрос Oracle
27th January, 09:58
916
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
907
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
941
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1725
0
период по дням
25th October, 10:44
3957
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3722
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4614
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4382
0
Помогите пожалуйста решить задачи
24th November, 23:53
6087
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4352
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4398
0
Метода Крамера С++
23rd October, 11:55
4309
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
Как получить свой собственный (локальный) IP-адрес из udp-сокета (C/C++)
- У вас есть несколько сетевых адаптеров.
- Привязка сокета UDP к локальному порту без указания адреса.
- Принимайте пакеты на одном из адаптеров.
Как вы получаете локальный ip-адрес адаптера, который получил пакет?
Вопрос в том, "What is the ip address from the receiver adapter?" не адрес от отправителя, который мы получаем в
receive_from( ..., &senderAddr, ... );
вызов.
Вы можете перечислить все сетевые адаптеры, получить их адреса IP и сравнить часть, покрытую маской подсети, с адресом отправителя.
Нравится:
IPAddress FindLocalIPAddressOfIncomingPacket( senderAddr )
{
foreach( adapter in EnumAllNetworkAdapters() )
{
adapterSubnet = adapter.subnetmask & adapter.ipaddress;
senderSubnet = adapter.subnetmask & senderAddr;
if( adapterSubnet == senderSubnet )
{
return adapter.ipaddress;
}
}
}
Добрый день,
Я предполагаю, что вы выполнили свою привязку, используя INADDR_ANY для указания адреса.
Если это так, то семантика INADDR_ANY такова, что сокет UDP создается на порту, указанном на всех ваших интерфейсах. Сокет собирается получить все пакеты, отправленные ко всем интерфейсам на указанном порту.
При отправке с помощью этого сокета используется самый низкий нумерованный интерфейс. В поле Адрес исходящего отправителя устанавливается адрес IP того первого используемого исходящего интерфейса.
Первый исходящий интерфейс определяется как последовательность, когда вы делаете ifconfig-a. вероятно, это будет eth0.
HTH.
овации, Грабить
Решение, предоставленное timbo , предполагает, что диапазоны адресов уникальны и не перекрываются. Хотя это обычно так, это не является универсальным решением.
Существует отличная реализация функции, которая делает именно то, что вам нужно, приведенная в книге Стивена "Unix network programming" (раздел 20.2) Это функция, основанная на recvmsg(), а не на recvfrom(). Если в вашем сокете включена опция IP_RECVIF, то recvmsg() вернет индекс интерфейса, на котором был получен пакет. Затем это можно использовать для поиска адреса назначения.
Исходный код доступен здесь . Рассматриваемая функция - 'recvfrom_flags()'
К сожалению, вызовы sendto и recvfrom API принципиально нарушаются при использовании с сокетами, привязанными к "Any IP", потому что у них нет поля для локальной информации IP.
Так что же вы можете с этим поделать?
- Вы можете догадаться (например, на основе таблицы маршрутизации).
- Вы можете получить список локальных адресов и привязать отдельный сокет к каждому локальному адресу.
- Вы можете использовать более новые APIs, которые поддерживают эту информацию. Есть две части этого, во-первых, вы должны использовать опцию сокета relavent (ip_recvif для IPv4, ipv6_recvif для IPv6), чтобы сообщить стеку, что вы хотите получить эту информацию. Затем вы должны использовать другую функцию (recvmsg на linux и несколько других unix-подобных систем, WSArecvmsg на windows), чтобы получить пакет.
Ни один из этих вариантов не является отличным. Угадывание, очевидно, приведет к неправильным ответам так часто. Привязка отдельных сокетов увеличивает сложность вашего программного обеспечения и вызывает проблемы, если список локальных адресов изменяется, когда ваша программа запущена. Более новые APIs являются правильным техническим решением, но могут снизить переносимость (в частности, похоже, что WSArecvmsg не доступен на windows XP) и могут потребовать изменения используемой библиотеки оболочки сокета.
Edit похоже, что я ошибся, похоже, что документация MS вводит в заблуждение и что WSArecvmsg доступно на windows XP. Увидеть https://stackoverflow.com/a/37334943/5083516
ssize_t
recvfrom(int socket, void *restrict buffer, size_t length, int flags,
struct sockaddr *restrict address, socklen_t *restrict address_len);
ssize_t
recvmsg(int socket, struct msghdr *message, int flags);
[..]
If address is not a null pointer and the socket is not connection-oriented, the
source address of the message is filled in.
Фактический код:
int nbytes = recvfrom(sock, buf, MAXBUFSIZE, MSG_WAITALL, (struct sockaddr *)&bindaddr, &addrlen);
fprintf(stdout, "Read %d bytes on local address %s\n", nbytes, inet_ntoa(bindaddr.sin_addr.s_addr));