Java Broadcasting:抛出BindException

时间:2015-09-04 17:57:42

标签: java sockets multicast multicastsocket

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

问题是我的客户端不知道服务器IP (在局域网中)。

所以我尝试使用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问题的正确方法吗?

谢谢!

2 个答案:

答案 0 :(得分:3)

正如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"));

答案 1 :(得分: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);

为服务器和客户端使用不同的端口号将允许您在同一台计算机上运行服务器应用程序和客户端应用程序,并让您超越此特定问题。