我正在构建一个程序,通过DatagramSocket和DatagramPacket将我局域网中的每台计算机连接到我的计算机(换句话说,我将成为服务器而其他人将成为客户端)。我做了一些研究并阅读了文档,并了解它是如何工作的,我实际上已经能够通过网络发送和接收数据。我在客户端类中有两个数据发送方法选项,我认为它们是等价的,但似乎没有。 第一个(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上发送数据和从我自己的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来说,真正的问题(以及实际的问题,很抱歉这么多,也许是无用的信息)。如果这是在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之间的区别吗?
答案 0 :(得分: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不是按规范连接,也不保证数据包的传送。