UDP数据包显示错误的IP地址

时间:2015-07-09 01:47:19

标签: java sockets networking tcp udp

我在繁忙的交通网络上收听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对象??

请告知并感谢您的光临。

1 个答案:

答案 0 :(得分:0)

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

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

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

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