需要帮助我的Java UDP客户端应用程序正常工作

时间:2015-11-25 16:06:30

标签: java sockets udp datagram

我正在使用UDP客户端与我无法控制的服务器进行通信。与此服务器通信的部分要求是我必须向服务器提供一个UDP端口号[作为消息的一部分]以进行回复通信。

我的应用程序中有几个类需要一个DatagramSocket,代表对该服务器的不同请求,所以我创建了一个静态类:

package mypackage;

import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;

public class DatagramSocketGrabber {

    public DatagramSocketGrabber(){}

    public static DatagramSocket getSocket() throws SocketException {
        DatagramSocket newSocket = new DatagramSocket();
        InetSocketAddress newSocketAddress = new InetSocketAddress(15346);
        newSocket.bind(newSocketAddress);
        return newSocket;
    }
}

在我的main()类中,我抓住这个套接字连接并在整个应用程序中使用它:

package mypackage;

import java.net.DatagramSocket;
import java.net.SocketException;

public class MyApp {
    public static void main(String[] args){
        DatagramSocket mySocket = null;

        try {
            mySocket = DatagramSocketGrabber.getSocket();
        } catch(SocketException se){
            System.out.println(se);
        }

        DSClass01 class01 = new DSClass01(mySocket);
        DSClass02 class02 = new DSClass02(mySocket);
        DSClass03 class03 = new DSClass03(mySocket);

        mySocket.close();
    }
}

但是,每当我运行我的应用程序时,我总是会收到错误:

  

java.net.SocketException:已绑定

需要知道

UDP服务器在我的机器上(localhost),但它是一个已编译的应用程序,因此我无法检查其代码。是的,它来自一个值得信赖的来源。

没有防火墙或网络问题,因为它是一台独立的计算机,所有东西都是敞开的。

在创建静态DatagramSocketGrabber类之前,我在所有消息类中创建了一个新的DatagramSocket,服务器能够成功接收我的消息。

然而,我创建静态类的原因是因为我没有收到任何回复,我确定这是因为我没有将我的套接字绑定到"固定"接收端口。为了做到这一点,并且能够在我的所有消息类中使用该绑定套接字,我想我需要创建一个DatagramSocket创建类,以便拥有一个可以传递的单个绑定套接字。

2 个答案:

答案 0 :(得分:1)

我的猜测是,因为你没有共享抛出SocketException的代码,所以是以下之一。

1)你在程序中第二次调用DatagramSocketGrabber.getSocket();,因此出现SocketException。

2)您留下了一些绑定到同一端口的代码(如new InetSocketAddress(15346);

尝试在代码中搜索套接字绑定(15346)并尝试查找程序中是否有其他DatagramSocketGrabber.getSocket();调用。

同时,您可以将DatagramSocketGrabber更改为单例并将DatagramSocket保留为属性,这样您就可以随时调用单例而不是将套接字传递给所有方法。

答案 1 :(得分:0)

好的......我明白了。经过一天的谷歌搜索后,我在StackOverflow上发现了 this 。我所要做的只是从

更改DatagramSocketGrabber
DatagramSocket newSocket = new DatagramSocket();

DatagramSocket newSocket = new DatagramSocket(null);

一切都按预期工作。解释如下:

  

为数据报套接字调用no-arg构造函数将导致它绑定到随机可用端口。一旦绑定,进一步尝试(重新)绑定将抛出套接字异常(带有您看到的错误)。要“延迟”绑定,您需要在未绑定状态下创建数据报套接字(通过在构造函数中传递null),然后再调用bind。

感谢Perception他/她的回答!