需要帮助让我的 Java UDP 客户端应用程序正常工作
Need assistance getting my Java UDP client application working
我正在使用 UDP 客户端与我无法控制的服务器进行通信。与此服务器通信的部分要求是我必须向服务器提供 UDP 端口号 [作为消息的一部分] 以进行回复通信。
我的应用程序中有几个 classes,它们需要一个 DatagramSocket,代表对该服务器的不同请求,所以我创建了一个静态 class:
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() class 中,我正在获取此套接字连接并在我的整个应用程序中使用它:
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: already bound
需要知道:
UDP 服务器在我的机器 (localhost) 上,但它是一个已编译的应用程序,所以我无法检查它的代码。是的,来源可靠。
没有防火墙或网络问题,因为它是一台独立的计算机,所有内容都是开放的。
在创建静态 DatagramSocketGrabber class 之前,我在所有消息 classes 中创建了一个新的 DatagramSocket,并且服务器能够成功接收我的消息。
但是,我创建静态 class 的原因是因为我没有收到任何回复,我确定这是因为我没有将我的套接字绑定到 "fixed" 接收端口。为了做到这一点,并能够在我的所有消息 classes 中使用该绑定套接字,我想我需要创建一个 DatagramSocket 创建 class 来拥有一个我可以的绑定套接字绕过去。
我的猜测是,由于您不共享抛出 SocketException 的代码是以下代码之一。
1) 您在程序中第二次调用 DatagramSocketGrabber.getSocket();
,因此出现 SocketException。
2) 您留下了一些绑定到同一端口的代码(如 new InetSocketAddress(15346);
)
尝试在您的代码中搜索套接字绑定 (15346),并尝试查找您的程序中是否有任何其他 DatagramSocketGrabber.getSocket();
调用。
同时,您可以将 DatagramSocketGrabber 更改为单例并将 DatagramSocket 保留为属性,这样您就可以始终调用单例而不是将套接字传递给所有方法。
好的...我明白了。经过一天的谷歌搜索,我在 Whosebug 上找到了 this post。我所要做的就是将 DatagramSocketGrabber 从
DatagramSocket newSocket = new DatagramSocket();
到
DatagramSocket newSocket = new DatagramSocket(null);
一切都按预期进行。解释是这样的:
Calling the no-arg constructor for a datagram socket will cause it to bind to a random, available port. Once bound, further attempts to (re)bind will throw a socket exception (with the error you were seeing). To 'defer' binding, you instead create the datagram socket in an unbound state (by passing a null in the constructor), then calling bind later on.
感谢 Perception 的 his/her 回答!
我正在使用 UDP 客户端与我无法控制的服务器进行通信。与此服务器通信的部分要求是我必须向服务器提供 UDP 端口号 [作为消息的一部分] 以进行回复通信。
我的应用程序中有几个 classes,它们需要一个 DatagramSocket,代表对该服务器的不同请求,所以我创建了一个静态 class:
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() class 中,我正在获取此套接字连接并在我的整个应用程序中使用它:
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: already bound
需要知道:
UDP 服务器在我的机器 (localhost) 上,但它是一个已编译的应用程序,所以我无法检查它的代码。是的,来源可靠。
没有防火墙或网络问题,因为它是一台独立的计算机,所有内容都是开放的。
在创建静态 DatagramSocketGrabber class 之前,我在所有消息 classes 中创建了一个新的 DatagramSocket,并且服务器能够成功接收我的消息。
但是,我创建静态 class 的原因是因为我没有收到任何回复,我确定这是因为我没有将我的套接字绑定到 "fixed" 接收端口。为了做到这一点,并能够在我的所有消息 classes 中使用该绑定套接字,我想我需要创建一个 DatagramSocket 创建 class 来拥有一个我可以的绑定套接字绕过去。
我的猜测是,由于您不共享抛出 SocketException 的代码是以下代码之一。
1) 您在程序中第二次调用 DatagramSocketGrabber.getSocket();
,因此出现 SocketException。
2) 您留下了一些绑定到同一端口的代码(如 new InetSocketAddress(15346);
)
尝试在您的代码中搜索套接字绑定 (15346),并尝试查找您的程序中是否有任何其他 DatagramSocketGrabber.getSocket();
调用。
同时,您可以将 DatagramSocketGrabber 更改为单例并将 DatagramSocket 保留为属性,这样您就可以始终调用单例而不是将套接字传递给所有方法。
好的...我明白了。经过一天的谷歌搜索,我在 Whosebug 上找到了 this post。我所要做的就是将 DatagramSocketGrabber 从
DatagramSocket newSocket = new DatagramSocket();
到
DatagramSocket newSocket = new DatagramSocket(null);
一切都按预期进行。解释是这样的:
Calling the no-arg constructor for a datagram socket will cause it to bind to a random, available port. Once bound, further attempts to (re)bind will throw a socket exception (with the error you were seeing). To 'defer' binding, you instead create the datagram socket in an unbound state (by passing a null in the constructor), then calling bind later on.
感谢 Perception 的 his/her 回答!