Tôi có một yêu cầu hơi kỳ lạ để có thể nghe một số giao diện mạng từ Java trên máy Linux và xác định xem một trong số chúng có nhận các gói UDP của loại nhất định. Dữ liệu đầu ra mà tôi cần là địa chỉ IP của giao diện được đề cập. Có cách nào để làm điều này trong Java?Java trên Linux: Nghe các tin nhắn phát sóng trên một địa chỉ cục bộ bị ràng buộc
Nghe địa chỉ ký tự đại diện (new DatagramSocket (port)) không hỗ trợ bởi vì trong khi tôi nhận được các gói tin phát sóng, tôi không thể xác định địa chỉ IP cục bộ của giao diện mà chúng đi qua. Lắng nghe các chương trình phát sóng trong khi bị ràng buộc với một giao diện nhất định (DatagramSocket mới (cổng, địa chỉ)) không nhận được các gói tin nào cả. Trường hợp này xứng đáng là một mã ví dụ trong đó cho thấy những gì tôi đang cố gắng để làm:
Enumeration interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
NetworkInterface ni = (NetworkInterface) interfaces.nextElement();
Enumeration addresses = ni.getInetAddresses();
while (addresses.hasMoreElements()) {
InetAddress address = (InetAddress)addresses.nextElement();
if (address.isLoopbackAddress() || address instanceof Inet6Address)
continue; //Not interested in loopback or ipv6 this time, thanks
DatagramSocket socket = new DatagramSocket(PORT, address);
//Try to read the broadcast messages from socket here
}
}
Tôi cũng đã cố gắng để khởi tạo các ổ cắm với địa chỉ quảng bá xây dựng dựa trên phần đầu của IP thực của giao diện và phần còn lại theo đúng mặt nạ mạng:
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);
Điều đó chỉ ném BindException khi xây dựng DatagramSocket.
EDIT: BindException (java.net.BindException: Không thể gán địa chỉ yêu cầu) từ gọi constructor DatagramSocket với một phát sóng địa chỉ (ví dụ 126.255.255.255) chỉ đi kèm với các mới nhất Ubuntu 9,04 (có lẽ không Ubuntu, nhưng hạt nhân vấn đề cụ thể -version). Với Ubuntu 8.10, công việc này cũng như với bản phát hành Red Hat (RHEL 4.x), tôi đang giải quyết.
Dường như không nhận được các gói trong khi được liên kết với một IP cục bộ nhất định là correct behaviour, mặc dù trong cửa sổ hoạt động. Tôi cần làm cho nó hoạt động trên Linux (RHEL và Ubuntu). Với mã C cấp thấp có một bộ giải mã (SO_BINDTODEVICE) mà tôi không thể tìm thấy trong các API Java. This không chính xác làm cho tôi bật với sự lạc quan mặc dù :-)
Dường như lỗi đó chưa được sửa trong 10 năm tới !! Khùng! : D –