2

我正在构建一个程序,它将通过 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)
 {
     ...
 }

当我在自己的 PC 上发送数据进行测试时,这两个选项出现了。我的 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 然后运行服务器时,显然没有得到任何数据,但也没有得到任何异常。真正的问题(和实际的问题,很抱歉有这么多,也许是无用的信息)是 Client2。如果这是在服务器之前运行的,我会得到 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 的新手,如果你知道没有人会收到它,那么发送数据似乎是错误的。另一方面,当服务器先运行,然后是 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之间的区别吗?

4

1 回答 1

2

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

就像在服务器上:

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

在客户端 2 上:

socket = new DatagramSocket(325, InetAddress.getByName("192.168.0.26"));

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

在客户端 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 不是规范的面向连接的,不保证数据包被传递。

于 2013-09-10T01:06:21.163 回答