[英]Cannot capture UDP broadcast packets with Java DatagramSocket
I am creating a client-server communication application and would like the client to be able to detect and connect to the server automatically, given that they are on the same network. 我正在创建一个客户端-服务器通信应用程序,并且希望客户端能够自动检测并连接到服务器,因为它们位于同一网络上。
Previously, my code was working across a Linux and Windows machine. 以前,我的代码是在Linux和Windows计算机上运行的。 I would broadcast a simple message and it could be read.
我会广播一条简单的消息,它可以被读取。 I could also see the message while watching network traffic with Wireshark.
在使用Wireshark观看网络流量时,我也可以看到该消息。
The approach I am taking is to 我正在采取的方法是
I am quite new to networking, so any obvious errors may not be immediately obvious to me. 我对联网很陌生,因此任何明显的错误可能对我来说都不是立即显而易见的。
Server broadcast code: 服务器广播代码:
public class Broadcaster {
/* ... */
public void pulse() throws InterruptedException, IOException, SocketException {
Long elapsed = new Date().getTime();
Long timeout = elapsed + this.duration;
DatagramPacket packet = new DatagramPacket(this.message.getBytes(), this.message.length());
HashSet<InetAddress> channels = Broadcaster.getBroadcastChannels();
while(elapsed <= timeout) {
for(InetAddress channel : channels) {
DatagramSocket socket = new DatagramSocket(this.port);
socket.setBroadcast(true);
socket.connect(channel, this.port);
socket.send(packet);
System.out.println("Broadcast sent to " + channel.getHostAddress() + " (" + socket.getPort() + "): " + this.message);
socket.close();
}
Thread.sleep(this.frequency);
elapsed = new Date().getTime();
}
}
private static HashSet<InetAddress> getBroadcastChannels() throws SocketException {
/* Returns 192.168.0.255 */
}
public static void main(String[] args) {
Broadcaster heart = new Broadcaster("Hello from the Raspberry Pi!", 120000, 5000, 8027);
try {
heart.pulse();
} catch(SocketException e) {
/* ...etc... */
} finally {
System.out.println("Broadcasting completed.");
}
}
}
Client code: 客户代码:
public class BroadcastListener {
private int port;
private int length;
public BroadcastListener(int length, int port) {
this.port = port;
this.length = length;
}
public String getNext() throws IOException {
byte buffer[] = new byte[this.length];
DatagramSocket socket = new DatagramSocket(this.port);
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
System.out.println("Waiting on " + socket.getLocalSocketAddress());
socket.receive(packet);
socket.close();
return new String(buffer);
}
public static void main(String[] args) {
System.out.println("Listening for network broadcasts...");
BroadcastListener broadcast = new BroadcastListener(128, 8027);
try {
System.out.println("Received broadcast: " + broadcast.getNext());
} catch(IOException e) {
System.out.println("Could not receive broadcasts:");
System.out.println(e.getMessage());
}
}
}
The broadcast/netmask address as seen on both devices ifconfig
output is netmask 255.255.255.0 broadcast 192.168.0.255
如看到的两个设备广播/掩码地址
ifconfig
输出是netmask 255.255.255.0 broadcast 192.168.0.255
What confuses me the most is that Wireshark is still seeing the broadcast but when I run the client Java program, it just sits at socket.receive(packet);
最让我感到困惑的是,Wireshark仍在观看广播,但是当我运行客户端Java程序时,它只是位于
socket.receive(packet);
Wireshark screenshot on Imgur Imgur上的Wireshark屏幕截图
Both client & server are on port 8027. It is clear that the broadcaster is working, but the client broadcast listener is not. 客户端和服务器都在端口8027上。很明显,广播服务器正在工作,但客户端广播侦听器却没有。 Does anyone have any idea what could be happening?
有谁知道会发生什么? Thanks!
谢谢!
As mentioned in the comments: Check your firewall :-) 如评论中所述:检查防火墙:-)
Another thing i recognized was that if I sniff with wireshark, no other processes could receive that datagrams. 我认识到的另一件事是,如果我嗅着Wireshark,其他进程将无法接收到该数据报。 After realizing that, I wrote a nodejs script, which exclusive=false by default but even that did not help.
在意识到这一点之后,我编写了一个nodejs脚本,默认情况下,exclusive = false仍然没有帮助。 Maybe there is a kernel flag or something, that UDP datagrams cannot be 'consumed' by one process.
也许有一个内核标志之类的东西,UDP数据报不能被一个进程“消耗”。
It looks like your server may be brodcasting on a different address than your client. 看来您的服务器可能在与客户端不同的地址上广播。 Your client is not being assigned an InetAddress, try using this constructor for your socket in
BroadcastListener
没有为您的客户端分配InetAddress,请尝试在
BroadcastListener
为套接字使用此构造函数
DatagramSocket socket = new DatagramSocket(new InetSocketAddress("192.168.0.255", this.port));
If that doesnt work you might try binding both your server and client to 127.0.0.1
如果这样不起作用,您可以尝试将服务器和客户端都绑定到
127.0.0.1
You keep creating and destroying DatagramSockets
. 您一直在创建和销毁
DatagramSockets
。 If the packet arrives at your host at a moment when you don't have a DatagramSocket
bound to the port, it will be thrown away. 如果数据包在您没有绑定到端口的
DatagramSocket
的瞬间到达主机,它将被丢弃。
Create one DatagramSocket
and leave it open for this life of this code. 创建一个
DatagramSocket
并在此代码的此期间保持打开状态。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.