Java 广播:抛出 BindException
Java Broadcasting: throw BindException
我希望我的客户端应用程序能够连接到服务器应用程序。
问题是我的客户端不知道服务器 ip(在 LAN 中)。
所以我尝试使用java对象MulticastSocket。幸运的是 Oracle 有一个带有 example of Broadcasting.
的页面
在这里我重新整理了它以供我使用。
服务器代码:
long FIVE_SECONDS = 5000;
int port = 4445;
DatagramSocket socket = new DatagramSocket(port);
while (true) {
System.out.println("Server running...");
try {
// message for client
String dString = "Hello Client";
byte[] buf = dString.getBytes();
// send
InetAddress group = InetAddress.getByName("230.0.0.1");
DatagramPacket packet = new DatagramPacket(buf, buf.length, group, port);
socket.send(packet);
// sleep for a while
try {
Thread.sleep((long)(Math.random() * FIVE_SECONDS));
}
catch (InterruptedException e) {
System.err.println("Interrupted Exception");
}
} catch (IOException e) {
System.err.println("IOException");
}
}
客户代码:
MulticastSocket socket = new MulticastSocket(4445);
InetAddress address = InetAddress.getByName("230.0.0.1");
socket.joinGroup(address);
// receive the message
byte[] buf = new byte[256];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
String received = new String(packet.getData(), 0, packet.getLength());
System.out.println("Received: " + received);
socket.leaveGroup(address);
socket.close();
当我 运行 服务器:没问题,但是当我尝试 运行 宁客户端时它抛出 java.net.BindException: Address already in use
因为客户端和服务器都是 listening/sending 关于 port 4445
.
但这不对吗? 要相互连接,它们必须具有相同的端口号,否则它们将永远'meet'。
我能解决这个问题吗?怎么样?
端口号是否正确?
这是解决未知服务器 ip 问题的正确方法吗?
谢谢!
您收到此异常是因为您试图 运行 您的服务器应用程序和您的客户端应用程序在同一台机器上。当您启动您的客户端时,您的服务器已经绑定到端口 4445,因此当您的客户端尝试绑定到它时它已经在使用中 - 因此不可用。
运行 你的服务器和你的客户端在不同的机器上会绕过那个特定的错误。但是,您也可以通过为服务器和客户端选择不同的端口来解决这个问题。
例如,如果您 运行 您的服务器在端口 4445 上,您的客户端在端口 4446 上,您可以执行以下操作。在服务器上,您将为客户端端口添加一个变量,并在发送 DatagramPacket 时使用客户端端口作为目标端口:
int clientPort = 4446;
...
DatagramPacket packet = new DatagramPacket(buf, buf.length, group, clientPort);
而不是
DatagramPacket packet = new DatagramPacket(buf, buf.length, group, port);
在客户端上,您只需绑定到客户端端口而不是服务器端口:
MulticastSocket socket = new MulticastSocket(4446);
而不是
MulticastSocket socket = new MulticastSocket(4445);
为服务器和客户端使用不同的端口号可以让您 运行 在同一台机器上同时使用服务器应用程序和客户端应用程序,从而解决这个问题。
正如沃伦在他的回答中提到的,您的客户端和服务器不能绑定到同一台机器上的同一端口。 Oracle 示例没有这样做。
客户端应该绑定到端口 4446,服务器应该绑定到端口 4445。当服务器创建一个 DatagramPacket
时,它应该使用客户端的端口 4446。
如果这样做,客户端还是收不到,可能需要在服务端设置组播的出接口。您可以使用 setInterface
或 setNetworkInterface
方法执行此操作。
例如,假设您的服务器的 IP 地址为 192.168.1.1 和 192.168.2.1。如果您希望发件人从 192.168.1.1 发送,您可以调用:
multicastSocket.setInterface(InetAddress.getByName("192.168.1.1"));
我希望我的客户端应用程序能够连接到服务器应用程序。
问题是我的客户端不知道服务器 ip(在 LAN 中)。
所以我尝试使用java对象MulticastSocket。幸运的是 Oracle 有一个带有 example of Broadcasting.
的页面在这里我重新整理了它以供我使用。
服务器代码:
long FIVE_SECONDS = 5000;
int port = 4445;
DatagramSocket socket = new DatagramSocket(port);
while (true) {
System.out.println("Server running...");
try {
// message for client
String dString = "Hello Client";
byte[] buf = dString.getBytes();
// send
InetAddress group = InetAddress.getByName("230.0.0.1");
DatagramPacket packet = new DatagramPacket(buf, buf.length, group, port);
socket.send(packet);
// sleep for a while
try {
Thread.sleep((long)(Math.random() * FIVE_SECONDS));
}
catch (InterruptedException e) {
System.err.println("Interrupted Exception");
}
} catch (IOException e) {
System.err.println("IOException");
}
}
客户代码:
MulticastSocket socket = new MulticastSocket(4445);
InetAddress address = InetAddress.getByName("230.0.0.1");
socket.joinGroup(address);
// receive the message
byte[] buf = new byte[256];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
String received = new String(packet.getData(), 0, packet.getLength());
System.out.println("Received: " + received);
socket.leaveGroup(address);
socket.close();
当我 运行 服务器:没问题,但是当我尝试 运行 宁客户端时它抛出 java.net.BindException: Address already in use
因为客户端和服务器都是 listening/sending 关于 port 4445
.
但这不对吗? 要相互连接,它们必须具有相同的端口号,否则它们将永远'meet'。
我能解决这个问题吗?怎么样?
端口号是否正确?
这是解决未知服务器 ip 问题的正确方法吗?
谢谢!
您收到此异常是因为您试图 运行 您的服务器应用程序和您的客户端应用程序在同一台机器上。当您启动您的客户端时,您的服务器已经绑定到端口 4445,因此当您的客户端尝试绑定到它时它已经在使用中 - 因此不可用。
运行 你的服务器和你的客户端在不同的机器上会绕过那个特定的错误。但是,您也可以通过为服务器和客户端选择不同的端口来解决这个问题。
例如,如果您 运行 您的服务器在端口 4445 上,您的客户端在端口 4446 上,您可以执行以下操作。在服务器上,您将为客户端端口添加一个变量,并在发送 DatagramPacket 时使用客户端端口作为目标端口:
int clientPort = 4446;
...
DatagramPacket packet = new DatagramPacket(buf, buf.length, group, clientPort);
而不是
DatagramPacket packet = new DatagramPacket(buf, buf.length, group, port);
在客户端上,您只需绑定到客户端端口而不是服务器端口:
MulticastSocket socket = new MulticastSocket(4446);
而不是
MulticastSocket socket = new MulticastSocket(4445);
为服务器和客户端使用不同的端口号可以让您 运行 在同一台机器上同时使用服务器应用程序和客户端应用程序,从而解决这个问题。
正如沃伦在他的回答中提到的,您的客户端和服务器不能绑定到同一台机器上的同一端口。 Oracle 示例没有这样做。
客户端应该绑定到端口 4446,服务器应该绑定到端口 4445。当服务器创建一个 DatagramPacket
时,它应该使用客户端的端口 4446。
如果这样做,客户端还是收不到,可能需要在服务端设置组播的出接口。您可以使用 setInterface
或 setNetworkInterface
方法执行此操作。
例如,假设您的服务器的 IP 地址为 192.168.1.1 和 192.168.2.1。如果您希望发件人从 192.168.1.1 发送,您可以调用:
multicastSocket.setInterface(InetAddress.getByName("192.168.1.1"));