【发布时间】:2013-12-30 18:09:48
【问题描述】:
我正在创建一个客户端-服务器通信应用程序,并希望客户端能够自动检测并连接到服务器,因为它们位于同一网络上。
以前,我的代码在 Linux 和 Windows 机器上运行。我会广播一条简单的消息,它可以被阅读。我还可以在使用 Wireshark 观看网络流量时看到该消息。
我采取的方法是
- 在服务器上获取网络上的广播地址。
- 在给定的持续时间内,广播一条消息(即将成为服务器 IP)
- 在客户端,等待收到消息。
我对网络很陌生,所以任何明显的错误对我来说可能不会立即显而易见。
服务器广播代码:
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.");
}
}
}
客户端代码:
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());
}
}
}
在两个设备ifconfig 输出上看到的广播/网络掩码地址是netmask 255.255.255.0 broadcast 192.168.0.255
最让我困惑的是,Wireshark 仍然看到广播,但是当我运行客户端 Java 程序时,它只是位于socket.receive(packet);
客户端和服务器都在端口 8027 上。很明显广播器正在工作,但客户端广播侦听器没有。有谁知道会发生什么?谢谢!
【问题讨论】:
标签: java sockets networking udp datagram