我正在使用服务器和客户端通过 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)
。
问题在于 receive
在 packet
上同步,并且 DatagramPacket
中的方法也是同步的,因此当第一个线程在 上被阻塞时receive(packet)
如果不阻塞线程,则无法调用任何 DatagramPacket
方法。
可能的解决方案包括在原始线程中处理数据包或为每个 receive()
创建一个新的 DatagramPacket
。
关于java - 为什么 DatagramPacket 对象在使用其方法之一时会卡住?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48388532/