gpt4 book ai didi

java - 为什么 DatagramPacket 对象在使用其方法之一时会卡住?

转载 作者:行者123 更新时间:2023-12-02 02:21:56 29 4
gpt4 key购买 nike

我正在使用服务器和客户端通过 UDP 数据包共享信息。
客户端组装数据包并将其发送到服务器。
服务器接收数据包,并发出一个线程来处理它

在线程代码中,我尝试使用数据包,但我使用的每种方法都陷入困境: getAddress() 、 getData() 等
当我尝试在服务器代码中使用数据包的方法时 - 它不会卡住。仅在线程中。
我不明白为什么在线程代码中使用数据包时会卡住

这是代码,它可以编译:
客户

public class ExchangeClientProgram
{
public final double ERROR = 0;
private DatagramPacket packet;
private DatagramSocket socket;
private InetAddress hostAddress;
private int port;
private byte [] buf;

public ExchangeClientProgram(String hostIp , int port) throws SocketException, UnknownHostException
{
this.port = port;
socket = new DatagramSocket();
hostAddress = InetAddress.getByName(hostIp);

}

public boolean sendRequestPacket(ExchangeRequest exchangeRequest)
{
try
{
buf = ExchangeServerProgram.convertObjectToByteArr(exchangeRequest);
if(null != buf)
{
packet = new DatagramPacket(buf, buf.length, hostAddress , port);
socket.send(packet);
return true;
}
else
JOptionPane.showMessageDialog(null, "Sorry, this exchange cannot be trasnmitted to server");

} catch (IOException e){e.printStackTrace();}

return false;
}


}

服务器

public class ExchangeServerProgram extends Thread
{
public static final int DEFAULT_SERVER_PORT = 4444;
public static final int DEFAULT_BUFFER_SIZE = 1024;
private DatagramSocket socket;
private DatagramPacket packet;
private boolean listening = false;// default initial value
private byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];

public ExchangeServerProgram() throws SocketException
{
socket = new DatagramSocket(DEFAULT_SERVER_PORT);
packet = new DatagramPacket(buffer , buffer.length);
}

public void run()
{
listening = true;
while(listening)
{
try
{
socket.receive(packet);
packet.getAddress(); // this line BEFORE the thread starts works fine.
new ExchangeClientRequestHandlerThread(packet ).start(); // inside this thread the trouble starts
// when using the SAME line from above

} catch (IOException e){e.printStackTrace();}

}

}

public static byte [] convertObjectToByteArr(Object obj)
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte [] buffer = null;
ObjectOutput out = null;
try {
out = new ObjectOutputStream(bos);
out.writeObject(obj);
out.flush();
buffer = bos.toByteArray();
}
catch (IOException e){e.printStackTrace(); }
finally {
try
{
bos.close();
} catch (IOException e){e.printStackTrace(); }
}

return buffer;
}
}

线程处理数据包,这就是我陷入困境的地方

public class ExchangeClientRequestHandlerThread extends Thread
{
private DatagramPacket packet;
public ExchangeClientRequestHandlerThread(DatagramPacket packet)
{
this.packet = packet;
}

public void run()
{
if(null == packet)
return;
packet.getAddress(); //... get stuck here

System.out.println("doesn't get to this code line");
}

}

交换请求

public class ExchangeRequest implements Serializable
{
private static final long serialVersionUID = -1355753051547829379L;
private String coinFrom;
private String coinTo;
private double amount;
private int requestId;

public ExchangeRequest(String coinFrom, String coinTo, double amount , int requestId)
{
this.coinFrom = coinFrom;
this.coinTo = coinTo;
this.amount = amount;
this.requestId = requestId;
}
//getters & setters

}

主要

public class Main
{
public static void main(String [] args)
{
try
{
ExchangeServerProgram server = new ExchangeServerProgram();
server.start(); // starts the server

String inputIpAddress = "localhost";
ExchangeClientProgram clientProgram = new ExchangeClientProgram(inputIpAddress, ExchangeServerProgram.DEFAULT_SERVER_PORT);
ExchangeRequest request = new ExchangeRequest("usd", "euro", 4, 1111); // 1111 is just an ID number for the message
clientProgram.sendRequestPacket(request);

while(true)
{
// this while loop is just for the example
// here I am waiting for received packet
// via "socket.receive();"
}
} catch (SocketException | UnknownHostException e)
{
e.printStackTrace();
}

}
}

最佳答案

线程是你的问题。您有一个线程调用 receive(packet),当您收到它时,您将其传递给另一个线程进行处理,从而使第一个线程再次调用 receive(packet)

问题在于 receivepacket 上同步,并且 DatagramPacket 中的方法也是同步的,因此当第一个线程在 上被阻塞时receive(packet) 如果不阻塞线程,则无法调用任何 DatagramPacket 方法。

可能的解决方案包括在原始线程中处理数据包或为每个 receive() 创建一个新的 DatagramPacket

关于java - 为什么 DatagramPacket 对象在使用其方法之一时会卡住?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48388532/

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