вероятно, отношение к модели объявления и пользователя
в модели AdDetail
public function ad()
{
return $this->belongsTo(Ad::class);
}
public function user()
{
return $this->belongsTo(User::class);
}
В конечном итоге это была проблема ядра Linux IPV6. Обычно я отключаю IPV6, потому что он вызывает всякие головные боли. Однако в Ubuntu 9.04 так сложно отключить IPV6, что я сдался, и это меня укусило.
Чтобы прослушивать широковещательные сообщения от определенного интерфейса, я сначала создам «широковещательную версию» IP-адреса интерфейса:
byte [] mask = { (byte)255, 0, 0, 0 };
byte[] addrBytes = InetAddress.getByName("126.5.6.7").getAddress();
for (int i=0; i < 4; i++) {
addrBytes[i] |= ((byte)0xFF) ^ mask[i];
}
InetAddress bcastAddr = InetAddress.getByAddress(addrBytes);
Конечно, это не привязывает меня к определенному интерфейсу, если у многих интерфейсов есть IP, который начинается с той же сетевой части, но для меня этого решения достаточно.
Затем я создаю датаграммный сокет с этим адресом (и желаемым портом), и он работает. Но не без передачи следующих системных свойств в JVM:
-Djava.net.preferIPv6Addresses=false -Djava.net.preferIPv4Stack=true
Я понятия не имею, как IPV6 удается прервать прослушивание широковещательных рассылок, но это происходит, и вышеуказанные параметры исправляют это.
Not sure if this helps but I know that to get a list of all the network interfaces:
Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces();
Maybe you can bind to each one independently?
Just found some great examples on the usage of getNetworkInterfaces().
Насколько мне известно, единственный способ сделать это - использовать параметр сокета
IP_RECVDSTADDR
. Эта опция должна гарантировать, что dst-адрес интерфейса, на который пришел пакет, доступен при привязке к подстановочному адресу. Полагаю, он должен работать и с широковещательной рассылкой.
Вот пример C, который я нашел в Интернете:
Как получить адрес назначения UDP для входящих пакетов
Я бы прочитал на recvmsg
, а затем попытайтесь выяснить, доступен ли этот интерфейс в Java.
Изменить:
Я только что понял, что у вас может быть еще один вариант, если он поддерживается в Java. Возможно, вам все еще понадобится параметр сокета IP_RECVDSTADDR
(не уверен), но вместо использования recvmsg вы можете использовать необработанный сокет и получить адрес назначения из заголовка IP.
Откройте сокет, используя SOCK_RAW
, и вы получите полный IP-заголовок в начале каждого сообщения, включая адреса источника и назначения.
Вот пример использования UDP с необработанным сокетом в C в Linux:
Advanced TCP / IP - ПРИМЕРЫ ПРОГРАММЫ RAW SOCKET
Я был бы удивлен, если этот метод не работает и в Java.
Edit2
Еще одна идея. Есть ли причина, по которой вы не можете использовать многоадресную рассылку, или какая-то конкретная причина, по которой вы выбрали широковещательную рассылку вместо многоадресной? Насколько я понимаю, с многоадресной рассылкой вы всегда будете знать, на каком интерфейсе принимаются пакеты, поскольку вы всегда привязываетесь к определенному интерфейсу при присоединении к группе многоадресной рассылки (особенно с IP4, где вы привязываетесь к интерфейсу через один из его IP-адресов).
Я получу полный IP-заголовок в начале каждого сообщения, включая адреса источника и назначения.Вот пример использования UDP с необработанным сокетом на C в Linux:
Advanced TCP / IP - ПРИМЕРЫ ПРОГРАММЫ RAW SOCKET
Я был бы удивлен, если этот метод не работает и в Java.
Edit2
Еще одна идея. Есть ли причина, по которой вы не можете использовать многоадресную рассылку, или какая-то конкретная причина, по которой вы выбрали широковещательную рассылку вместо многоадресной? Насколько я понимаю, с многоадресной рассылкой вы всегда будете знать, на каком интерфейсе принимаются пакеты, поскольку вы всегда привязываетесь к определенному интерфейсу при присоединении к группе многоадресной рассылки (особенно с IP4, где вы привязываетесь к интерфейсу через один из его IP-адресов).
Я получу полный IP-заголовок в начале каждого сообщения, включая адреса источника и назначения.Вот пример использования UDP с необработанным сокетом в C в Linux:
Advanced TCP / IP - ПРИМЕРЫ ПРОГРАММЫ RAW SOCKET
Я был бы удивлен, если этот метод не работает и в Java.
Edit2
Еще одна идея. Есть ли причина, по которой вы не можете использовать многоадресную рассылку, или какая-то конкретная причина, по которой вы выбрали широковещательную рассылку вместо многоадресной? Насколько я понимаю, с помощью многоадресной рассылки вы всегда будете знать, на каком интерфейсе принимаются пакеты, поскольку вы всегда привязываетесь к определенному интерфейсу при присоединении к группе многоадресной рассылки (особенно с IP4, где вы привязываетесь к интерфейсу через один из его IP-адресов).
s пример использования UDP с необработанным сокетом в C в Linux:Advanced TCP / IP - ПРИМЕРЫ ПРОГРАММЫ RAW SOCKET
Я был бы удивлен, если этот метод не работает и в Java.
Edit2
Еще одна идея. Есть ли причина, по которой вы не можете использовать многоадресную рассылку, или какая-то конкретная причина, по которой вы выбрали широковещательную рассылку вместо многоадресной? Насколько я понимаю, с помощью многоадресной рассылки вы всегда будете знать, на каком интерфейсе принимаются пакеты, поскольку вы всегда привязываетесь к определенному интерфейсу при присоединении к группе многоадресной рассылки (особенно с IP4, где вы привязываетесь к интерфейсу через один из его IP-адресов).
s пример использования UDP с необработанным сокетом в C в Linux:Advanced TCP / IP - ПРИМЕРЫ ПРОГРАММЫ RAW SOCKET
Я был бы удивлен, если этот метод не работает и в Java.
Edit2
Еще одна идея. Есть ли причина, по которой вы не можете использовать многоадресную рассылку, или какая-то конкретная причина, по которой вы выбрали широковещательную рассылку вместо многоадресной? Насколько я понимаю, с многоадресной рассылкой вы всегда будете знать, на каком интерфейсе принимаются пакеты, поскольку вы всегда привязываетесь к определенному интерфейсу при присоединении к группе многоадресной рассылки (особенно с IP4, где вы привязываетесь к интерфейсу через один из его IP-адресов).
Не используете многоадресную рассылку или по какой-то конкретной причине вы выбрали широковещательную рассылку вместо многоадресной? Насколько я понимаю, с многоадресной рассылкой вы всегда будете знать, на каком интерфейсе принимаются пакеты, поскольку вы всегда привязываетесь к определенному интерфейсу при присоединении к группе многоадресной рассылки (особенно с IP4, где вы привязываетесь к интерфейсу через один из его IP-адресов). Не используете многоадресную рассылку или по какой-то конкретной причине вы выбрали широковещательную рассылку вместо многоадресной? Насколько я понимаю, с многоадресной рассылкой вы всегда будете знать, на каком интерфейсе принимаются пакеты, поскольку вы всегда привязываетесь к определенному интерфейсу при присоединении к группе многоадресной рассылки (особенно с IP4, где вы привязываетесь к интерфейсу через один из его IP-адресов).Чтобы повторить проблему, вам необходимо определить, на какой интерфейс были получены широковещательные UDP-пакеты.
Как уже упоминалось другими, существуют сторонние библиотеки сырых сокетов для Java, такие как RockSaw или Jpcap , которые могут помочь вам определить адрес фактического интерфейса.
Не могу комментировать, поэтому добавляю это в качестве ответа.
Это интересно. Хотя мне любопытно, почему вы используете
byte[] addrBytes = InetAddress.getByName("126.5.6.7").getAddress();
, а не просто
byte[] addrBytes = {126, 5, 6, 7);
, или адреса интерфейсов попадают к вам как String?