【问题标题】:UDP packet shows wrong ip addressUDP数据包显示错误的IP地址
【发布时间】: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


【解决方案1】:

您的问题可能是竞争条件。也许还有其他问题,但我不能说。

只需查看您的代码即可。这不应该吗

Packet packet = (Packet)lbq.poll();

成为关键部分的一部分并具有同步访问权限?这是唯一不受保护的对 lbq 的访问。似乎它应该在 while 循环之后的同步部分内。

【讨论】:

    猜你喜欢
    • 2011-01-30
    • 1970-01-01
    • 2017-05-13
    • 2020-03-11
    • 2018-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-13
    相关资源
    最近更新 更多