【问题标题】:Garbage output after parsing UDP packet解析UDP数据包后的垃圾输出
【发布时间】:2016-07-21 19:57:34
【问题描述】:

我正在尝试从 UDP 数据包中提取信息,但不断得到随机输出。有时我得到我想要的,有时却没有。

这是我的代码:

private static void receivePacket()
{
    try {
        DatagramSocket socket = new DatagramSocket(port);
        System.out.println("\n  Listening...");

        while(true)
        {
            // Create a packet
            DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);

            // Receive packet
            socket.receive(packet);
            byte[] data = packet.getData();

            // Parse the packet
            parse(data, packet.getLength());

            socket.send(packet);
         }

        } catch(Exception e) {
            e.printStackTrace();
        }
}

// Parse packets
private static void parse(byte [] data, int dataLength)
{
    ArrayList<String> name = new ArrayList<String>()
    String domain = "";

    // Get ID
    int id = ((data[0] & 0xff) << 8) + (data[1] & 0xff);
    System.out.println("\n  ID:\t\t" + id);

    // Get domain name and number of bits for each word in domain
    for(int i = 0; i < dataLength; i++)
    {
        // If the next bit is a letter then we know the current bit is the number of bits
        if((data[i] <= ' ') || (data[i] > '~'))
        {
            try {
                if((String.format("%c", data[i+1]).matches("^[a-zA-Z]$")))
                {
                    int dSize = Integer.parseInt(String.format("%d", data[i]));
                    name.add(Integer.toString(dSize));
                }

            } catch (Exception e) {
                //e.printStackTrace();
            }
        }
        else
        {
            // If current bit is letter add to ArrayList
            try {
                if((String.format("%c", data[i]).matches("^[a-zA-Z]$")))
                {
                    name.add(String.format("%c", data[i]));
                    domain += String.format("%c", data[i]);
                }

            } catch (Exception e) {
                //e.printStackTrace();
            }
        }
    }

    System.out.println("  Domain:\t" + domain);
    System.out.print("  Name:\t\t");
    name.add("0");

    for(int i = 0; i < name.size(); i++)
        System.out.print("\'" + name.get(i) + "\' ");

    System.out.println();
 }

我使用dig 命令dig @localhost -p 1299 test.mydomain.abc 向服务器发送一个UDP 数据包。这是我运行六次后的输出。每次的输出应该如下(ID会有所不同):

ID:           64666
Domain:       testmydomainabc
Name:         '4' 't' 'e' 's' 't' '8' 'm' 'y' 'd' 'o' 'm' 'a' 'i' 'n' '3' 'a' 'b' 'c' '0'

但是,从第 4 次运行开始,情况并非如此:

这是完全随机的,我不明白为什么。我在 Java 和 Windows 10 上对此进行编码。任何帮助将不胜感激,谢谢!

原始数据:

试用成功:'4' 't' 'e' 's' 't' '8' 'm' 'y' 'd' 'o' 'm' 'a' 'i' 'n' '3' 'a' 'b' 'c' '0'

b7 01 20 00 01 00 00 00 00 00 01 04 t e s t 08 m y d o m a i n 03 a b c 00 00 01 00 01 00 00 ) 10 00 00 00 00 00 00 00

不成功:'-127' 'f' '4' 't' 'e' 's' 't' '8' 'm' 'y' 'd' 'o' 'm' 'a' 'i' 'n' '3' 'a' 'b' 'c' '0'

81 f 01 20 00 01 00 00 00 00 00 01 04 t e s t 08 m y d o m a i n 03 a b c 00 00 01 00 01 00 00 ) 10 00 00 00 00 00 00 00

【问题讨论】:

  • 简单地打印出存储在packet.getData() 中的原始数据以查看问题是发生在网络期间还是在您的解析算法中可能很有用。 (当然,添加到问题主体中也很有用)
  • 在正确的轨道上。我要的是产生预期输出的试验的原始数据和产生不良输出的试验的原始数据。然后我们可以比较两者(并改进你的解析算法来处理我们发现的问题)。
  • 完美。看看您发布的内容,看起来它们完全相同,但有一个例外:不成功的数据包在开始时有两个字节(81 和 f),而成功的数据包有一个(b7)。你在你的解析算法中处理这种行为吗?
  • 我不知道,因为我不熟悉dig。您应该阅读有关它实际功能的复杂细节。我最好的猜测是,如果你在两次试验中出现的“01 20 00 01”序列之后开始,你应该没问题。
  • 我会阅读它。非常感谢你的帮助!从中了解了有关调试的更多信息。

标签: java sockets parsing udp datagram


【解决方案1】:

parse 中的循环从 0 开始,可能应该从 2 开始。否则 ID 字节将包含在 Domain 解析中(或抛出一个被静默忽略的异常)

【讨论】:

  • 谢谢,snickers10m 实际上帮我解决了这个问题。我将从2 开始,而不是我使用的12
猜你喜欢
  • 1970-01-01
  • 2015-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-29
  • 2010-11-24
  • 2013-01-22
相关资源
最近更新 更多