gpt4 book ai didi

java - 如何在线程中继续尝试获取 Java DatagramSocket?

转载 作者:行者123 更新时间:2023-12-02 03:59:42 26 4
gpt4 key购买 nike

我正在开发 Java UDP 应用程序。应用程序中有一个线程,其唯一的工作是监听特定端口上的服务器。

我编写应用程序时错误地假设我正在监听的服务器将始终处于运行状态;然而,这是一个错误的假设。

如果我的应用程序在服务器运行后启动,则一切正常。如果我的应用程序在服务器启动之前启动,或者在我的应用程序运行时重新启动服务器,我的应用程序就会中断。

MainClass.java

public class MainClass {
public static void main(String[] args){
ListeningClass myListeningClass = new ListeningClass();
Thread listenerThread = new Thread(myListeningClass);
listenerThread.setName("My Listening Thread");
listenerThread.start();
}
}

ListeningClass.java

public class ListeningClass implements Runnable {
private volatile boolean run = true;
private byte[] receiveBuffer;
private int receiveBufferSize;
private DatagramSocket myDatagramSocket;
private DatagramPacket myDatagramPacket;

@Override
public void run(){
try {
myDatagramSocket = new DatagramSocket(null);
InetSocketAddress myInetSocketAddress = new InetSocketAddress(15347);
myDatagramSocket.bind(myInetSocketAddress);

receiveBuffer = new byte[2047];
myDatagramPacket = new DatagramPacket(receiveBuffer, 2047);

while(run){
myDatagramSocket.receive(myDatagramPacket);
byte[] data = myDatagramPacket.getData();
receiveBufferSize = myDatagramPacket.getLength();
// process the data received here
}
} catch (SocketException se){
// do stuff
} catch (IOException ioe){
// do stuff
}
}

public boolean isRun(){
return run;
}

public void setRun(boolean run){
this.run = run;
}
}

就像我说的,如果我的应用程序在服务器运行后启动,一切都会完美运行,正如预期的那样。但是,如果我的应用程序在服务器运行之前启动,那么什么都不起作用。显然,这是因为线程尝试打开连接一次,如果失败,则不会再尝试。

我将 DatagramSocket 打开代码移至 while block 内,但这并不漂亮。我收到一堆“端口已绑定(bind)”错误。

那么,我该如何重建它才能正常工作?

最佳答案

这并不是一个真正的并发问题。您只需要检查接收时抛出的异常并进行适当的处​​理。在这种情况下,请重新绑定(bind)套接字。请参阅docs用于接收

例如:

...
while(run) {
try {
myDatagramSocket.receive(myDatagramPacket);
byte[] data = myDatagramPacket.getData();
receiveBufferSize = myDatagramPacket.getLength();
// process the data received here
} catch (IOException ioe) {
// Perhaps use PortUnreachableException but not guaranteed
rebind(myDatagramSocket, myInetSocketAddress);
}
}

private void rebind(DatagramSocket s, InetSocketAddress addr) {
s.bind(addr);
}

我认为这应该足够了。关键是,只有当您的接收表明服务器存在 I/O 问题时,您才需要重新绑定(bind)。如果您将绑定(bind)放在循环中,那么您将为每个接收进行绑定(bind) - 这在您的快乐路径情况下是可以的。

关于java - 如何在线程中继续尝试获取 Java DatagramSocket?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35065839/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com