【问题标题】:Java Broadcasting: throw BindExceptionJava 广播:抛出 BindException
【发布时间】:2015-09-04 17:57:41
【问题描述】:

我希望我的客户端应用程序能够连接到服务器应用程序。

问题是我的客户端不知道服务器 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();

当我运行 Srver 时:没问题,但是当我尝试运行客户端时它抛出 java.net.BindException: Address already in use 导致客户端和服务器都在 port 4445 上侦听/发送信息。

但不是吗? 要相互连接,它们必须具有相同的端口号,否则它们将永远不会“相遇”

我可以解决这个问题吗?怎么样?

端口号是否正确?

这是对未知服务器 ip 问题的正确解决方案吗?

谢谢!

【问题讨论】:

  • 虽然我无法回答这个问题,但同一端口上的两个侦听器将无法正常工作。一个端口就像一个 IO 流,当有两个写入器/读取器时,就会发生不好的事情。这就是为什么抛出 BindException 以防止坏事发生的原因。
  • @WorldSEnder :可能你是对的,但是在我的问题(和here)中链接的 Oracle 示例中,它们使用相同的端口号......
  • 你运行了他们的例子吗?如果不是,您的客户端和服务器是否在同一台计算机上?如果是,那我可以解释问题,如果不是,我不知道
  • @WorldSEnder 是的,我在同一台计算机上使用客户端和服务器运行他们的示例。它会影响什么吗?
  • “但不是吗?要相互连接,它们必须具有相同的端口号,否则它们将永远不会‘相遇’。”不,这是不对的。发送方发送到接收方的端口。它们不必相同。

标签: java sockets multicast multicastsocket


【解决方案1】:

正如 Warren 在他的回答中提到的,您的客户端和服务器不能绑定到同一台机器上的同一个端口。 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"));

【讨论】:

    【解决方案2】:

    您收到此异常是因为您尝试在同一台机器上运行服务器应用程序和客户端应用程序。当您启动客户端时,您的服务器已经绑定到端口 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);
    

    为服务器和客户端使用不同的端口号将允许您在同一台机器上同时运行服务器应用程序和客户端应用程序,从而解决这个特定问题。

    【讨论】:

    • 感谢您的回答,但您的更改并没有解决问题:在同一台机器上客户端找不到服务器的数据包。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-27
    • 1970-01-01
    • 2019-10-10
    • 1970-01-01
    • 2014-06-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多