我正在构建一个程序,该程序将通过DatagramSocket和DatagramPacket将LAN中的每台计算机连接到我的计算机(换句话说,我将是服务器,其他人将是客户端)。我进行了一些研究,阅读了文档,发现了它是如何工作的,实际上,我已经能够通过网络发送和接收数据。客户端类中的数据发送方法有两个选项,我认为这是等效的,但似乎没有。
第一个(Client1):

DatagramSocket socket = null;
DatagramPacket packet = null;

try
{
     byte[] data= "test".getBytes();
     packet = new DatagramPacket(data, data.length, InetAddress.getByName("192.168.0.26"), 325);
     socket = new DatagramSocket();
     socket.send(packet);
 }
 catch (Exception ex)
 {
     ...
 }

第二个(Client2):
DatagramSocket socket = null;
DatagramPacket packet = null;

try
{
     byte[] data= "test".getBytes();
     packet = new DatagramPacket(data, data.length);
     socket = new DatagramSocket(325, InetAddress.getByName("192.168.0.26"));
     socket.send(packet);
 }
 catch (Exception ex)
 {
     ...
 }

当我进行测试时,这两个选项就出现了。我的IP地址是192.168.0.26。对于第一个,我没有问题,但是第二个抛出两种异常。我可以验证Client1是否可以同时运行计算机中的下一个代码

(服务器)
byte data[] = null;
try
{
    data= new byte[1000];
    socket = new DatagramSocket(325);
    packet = new DatagramPacket(datos, datos.length);
    socket.receive(packet);
    System.out.println(datos);
}
catch (Exception ex)
{
    ...
}

如果我先运行Server,然后再运行Client1选项,则它实际上会接收数据。当我先运行Client1然后再运行Server时,显然没有任何数据,但也没有任何异常。真正的问题(也是实际的问题,对这么多,可能是无用的信息感到抱歉)是与Client2有关的。如果这是在Server之前运行的,则会收到NullPointerException:
java.lang.NullPointerException: null address || null buffer
at java.net.DualStackPlainDatagramSocketImpl.send(DualStackPlainDatagramSocketImpl.java:115)
at java.net.DatagramSocket.send(DatagramSocket.java:676)

调用方法send()时生成。我知道也许我应该忽略这个;甚至以为我是Socket的新手,如果您知道没人能接收数据,则发送数据似乎是错误的。另一方面,当先运行Server然后运行Client2时,我得到BindException:
java.net.BindException: Address already in use: Cannot bind
at java.net.DualStackPlainDatagramSocketImpl.socketBind(Native Method)
at java.net.DualStackPlainDatagramSocketImpl.bind0(DualStackPlainDatagramSocketImpl.java:65)
at java.net.AbstractPlainDatagramSocketImpl.bind(AbstractPlainDatagramSocketImpl.java:95)
at java.net.DatagramSocket.bind(DatagramSocket.java:376)
at java.net.DatagramSocket.<init>(DatagramSocket.java:231)
at java.net.DatagramSocket.<init>(DatagramSocket.java:284)

从套接字初始化时的行开始。
由于Client1可以正常工作,因此我将使用它。但是我真的很想知道为什么它能工作,但是Client2却不能。我在这里的另一个论坛上阅读了有关BindException的信息,我了解到它是当您尝试使用已经使用的一个端口时引起的,但是从这种意义上讲Client1也应该失败。有人可以解释一下Client1和Client2之间的区别吗?

最佳答案

您要绑定(bind)到同一端口,如果要在同一台机器/地址上运行它,则需要绑定(bind)到不同的端口。

就像在服务器上一样:

socket = new DatagramSocket(325);    //server binds its UDP/IP socket to port 325

在客户端2上:
socket = new DatagramSocket(325, InetAddress.getByName("192.168.0.26"));

您将绑定(bind)到“服务器”正在使用的同一台机器/地址上的同一端口

在客户端1上:
packet = new DatagramPacket(data, data.length, InetAddress.getByName("192.168.0.26"), 325);
//you are specifying the destination address and port the packet should be sent.
socket = new DatagramSocket();
//but in the DatagramSocket contructor you don't pass any address or port to bind to, so it will use an available port, not 325 as it is in use by the server.

正如您所说的,您刚接触网络通信时,请记住这是UDP/IP套接字,TCP/IP等。 UDP/IP不是按规范面向连接的,并且不能保证要发送的数据包。

关于java - 为什么不同的DatagramSocket构造函数表现得如此不同? (BindException),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18709234/

10-12 02:32