【发布时间】:2015-07-09 01:47:18
【问题描述】:
我正在一个流量大的网络上收听 UDP 数据包。 Wireshark 捕获显示 UDP 数据包 IP 地址为 125.6.6.5 但是当我的代码“NetworkListener.java”监听数据包时,我看到它打印出正确的信息,但我确实传入了这些数据并构造了一个新对象“数据包”,然后放入 LinkedBlockingQueue 并在另一个类“Worker.java”中读取它。 当我在 Worker.java 类中打印相同的数据包时,我看到数据包的 IP 地址已更改。
由于它是一个交通繁忙的网络,我在一秒钟内在该端口上收到超过 40 个数据包,并且我将其转换为差异对象并存储在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 中的打印语句,我希望它们是给定有效负载的相同 IP 地址,但在我的情况下,有时它给我正确的 IP 地址,有时它给出一个错误的 IP 地址。每秒钟,我都会看到队列中要处理大约 35 个数据包。
我做错了什么???
我的代码无法处理繁重的流量吗? 我应该使用除 LinkedBlockingQueue 之外的任何其他数据结构吗? 还是我不应该从 DatagramPacket 转换为 Packet 对象??
请提供建议并感谢您的关注。
【问题讨论】:
-
我认为您可能误解了 Wireshark 的输出。您的 Java 应用程序可能不是唯一生成活动的东西。
-
不,我确实验证了wireshark并确保数据正确,因为我们从另一个网络获取数据,甚至wireshark捕获显示相同。与IP地址相关的数据也是正确的,所以它在代码中。
-
从添加实际的异常处理程序开始。现在,异常会被默默地丢弃,因此数据包处理中的错误可能会导致您的应用程序丢失一些。您甚至可能认为您正在观看这个确切的数据包,而实际上您并没有。而且,顺便说一句,你的代码剪断应该更多...... minimal.
-
我没有在这里记录异常......但我确实记录了这些,但我没有看到任何记录。
标签: java sockets networking tcp udp