我在繁忙的交通网络上收听UDP数据包。 wireshark捕获显示UDP数据包的IP地址为125.6.6.5但是当我的代码" NetworkListener.java"收听数据包时,我看到它打印出正确的信息,但我确实传递了这些数据并构建一个新对象" Packet"然后放入LinkedBlockingQueue并在另一个类" Worker.java"中读取它。 当我在Worker.java类中打印相同的数据包时,我看到数据包的IP地址已被更改。
由于它是一个繁忙的交通网络,我在该端口上一秒钟内获得了超过40个数据包,并且我将其转换为diff对象并存储在linkedBlockingQueue中,数据包是否在队列中发生冲突并给出我错了ip ???
java类是:
public class NetworkListener implements Runnable
{
private LinkedBlockingQueue lbq;
private volatile boolean running;
public NetworkListener()
{
lbq = PacketQueue.getInstance();
running = true;
}
public void run()
{
try
{
byte[] rwhat = new byte[1024];
DatagramPacket packet = new DatagramPacket(rwhat, 1024);
// Setup listener on port 5000
InetSocketAddress isock = new InetSocketAddress(5000);
DatagramSocket datagramSocket = new DatagramSocket(null);
datagramSocket.setReuseAddress(true);
datagramSocket.bind(isock);
datagramSocket.setSoTimeout(15000); // 15 seconds timeouts
// loop reading packets
while (running)
{
try {
datagramSocket.receive(packet);
}
catch (SocketTimeoutException te) {
continue;
}
String ipAddr = new String (packet.getAddress().getHostAddress());
String payLoad = new String (packet.getData());
String strRecv = new String( "IP Address from Network Listener:[" + ipAddr + "], Payload :[" + payLoad + "]");
System.out.println(strRecv);
synchronized (lbq)
{
lbq.put(new Packet(packet.getData(), packet.getAddress().getHostAddress()));
lbq.notifyAll();
}
}
}
catch (Exception e)
{
}
}
/**
* Shutdown current thread
*/
public void shutdown()
{
running = false;
if (lbq != null)
{
synchronized (lbq)
{
lbq.notifyAll();
lbq = null;
}
}
}
}
public class Packet
{
private byte[] bytes;
private String ipAddress;
public Packet(final byte[] bytes, final String ipAddress)
{
this.bytes = bytes;
this.ipAddress = ipAddress;
}
public byte[] getBytes()
{
return bytes;
}
public String getipAddress()
{
return ipAddress;
}
}
public class PacketQueue extends LinkedBlockingQueue
{
private static volatile PacketQueue INSTANCE = null;
public static synchronized final PacketQueue getInstance()
{
if (INSTANCE == null)
INSTANCE = new PacketQueue();
return INSTANCE;
}
}
public class Worker implements Runnable
{
private LinkedBlockingQueue lbq;
private volatile boolean running;
public Worker()
{
lbq = PacketQueue.getInstance();
running = true;
}
public void run()
{
System.out.println("Thread Starting Up . . .");
while (running)
{
synchronized (lbq)
{
while (lbq.empty())
{
try
{
lbq.wait();
if (lbq == null)
return;
}
catch (InterruptedException e)
{
return;
}
}
}
Packet packet = (Packet)lbq.poll();
if (packet != null)
{
String ipAddr = new String (packet.getipAddress());
String payLoad = new String (packet.getBytes());
String strRecv = new String( "IP Address from Worker:[" + ipAddr + "], Payload :[" + payLoad + "]");
System.out.println(strRecv);
}
}
}
/**
* Shutdown current thread
*/
public void shutdown()
{
running = false;
if (lbq != null)
{
synchronized (lbq)
{
lbq.notifyAll();
lbq = null;
}
}
}
}
因此,如果我要比较NetworkListener.java和Worker.java中的两个print语句,我希望它们与给定的有效负载相同,但在我的情况下,有时候它会给我正确的ip地址,有时它会给出一个不正确的IP地址。每一秒,我都会看到大约35个数据包要在队列中处理。
我做错了什么???
我的代码无法处理繁忙的流量吗? 我应该使用除LinkedBlockingQueue之外的任何其他数据结构吗? 或者我不应该从DatagramPacket转换为Packet对象??
请告知并感谢您的光临。
答案 0 :(得分:0)
您的问题可能是竞争条件。也许其他问题可能但我不能说。
只需查看您的代码即可。不应该这个
Packet packet = (Packet)lbq.poll();
成为关键部分的一部分并具有同步访问权限?这是对未受保护的lbq的唯一访问。似乎它应该在while循环之后的synchronized部分内。