0

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

问题是我的客户端不知道服务器 ip(在 LAN 中)。

所以我尝试使用 java 对象MulticastSocket。幸运的是,Oracle 有一个带有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 问题的正确解决方案吗?

谢谢!

4

2 回答 2

3

正如 Warren 在他的回答中提到的,您的客户端和服务器不能绑定到同一台机器上的同一个端口。Oracle 示例没有这样做。

客户端应该绑定到端口 4446,服务器应该绑定到端口 4445。当服务器创建一个DatagramPacket时,它应该使用客户端的端口 4446。

如果你这样做了,客户端仍然无法接收,你可能需要在服务器上设置多播的传出接口。您可以使用setInterfaceorsetNetworkInterface方法执行此操作。

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

multicastSocket.setInterface(InetAddress.getByName("192.168.1.1"));
于 2015-09-07T00:29:34.323 回答
1

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

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

于 2015-09-04T21:02:07.597 回答