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。

如果这样做,客户端还是收不到,可能需要在服务端设置组播的出接口。您可以使用 setInterfacesetNetworkInterface 方法执行此操作。

例如,假设您的服务器的 IP 地址为 192.168.1.1 和 192.168.2.1。如果您希望发件人从 192.168.1.1 发送,您可以调用:

multicastSocket.setInterface(InetAddress.getByName("192.168.1.1"));