2011-12-21 1 views
2

При работе над Java-приложением под Mac OS X (Lion, 10.7.2, Java-версия «1.6.0_29») я столкнулся с странной проблемой при попытке отправить многоадресные датаграммы UDP. Пакеты отправляются только на одну сетевую карту, и я не могу контролировать, какой из них.Передача многоадресной рассылки UDP на неправильной сетевой карте (Java, Mac OS X)

Следующий пример кода иллюстрирует то, что я пытаюсь сделать:

public class MCast { 
    public static void main(String[] args) throws IOException { 
     InetAddress multicastAddr = InetAddress.getByName("224.0.0.1"); 
     int port = 58680; 
     byte[] data = "test".getBytes(); 

     DatagramPacket packet = new DatagramPacket(data, data.length, multicastAddr, port); 

     MulticastSocket socket = new MulticastSocket(); 
     socket.joinGroup(multicastAddr); 
     socket.setNetworkInterface(NetworkInterface.getByName("en0")); 

     socket.send(packet); 
     System.out.println("Packet sent."); 
    } 
} 

Хотя выполнения этого кода, я использую Wireshark, чтобы исследовать весь трафик собирается на en0. В указанном порту пакеты не отправляются. Однако указанные пакеты появляются на трассе для en1.

Когда я отключу en1, пакеты правильно идут на en0.

Я в затруднении здесь. Кто-нибудь знает, что происходит?

ответ

0

Вы можете передать адрес конструктору MulticastSocket. Вы можете использовать его для привязки к адресу, который вы хотите.

+0

Обычно это будет выполнять эту работу. К сожалению, характер службы, которую я пишу, требует, чтобы она была на порте, уже используемом другим приложением, и попытка связать с ним бросает «BindException». Спасибо за попытку. EDIT: Или я могу использовать свой мозг и сказать, чтобы он связывался с портом 0. Спасибо! – Terrana

6

Интерфейс вывода многоадресной передачи определяется текущей таблицей маршрутизации во время объединения группы. В большинстве случаев это означает маршрут по умолчанию, следовательно, en0. Добавление явного маршрута поможет, но вы можете просто поменять местами две строки в коде, чтобы быть:

socket.setNetworkInterface(NetworkInterface.getByName("en0")); 
socket.joinGroup(multicastAddr); 

Кроме того, вам не нужно, чтобы присоединиться (ни bind()) группа, если вы только отправка и не прослушивая этот многоадресный трафик. Вместо этого, connect() на адрес группы.