这个程序是一个IP数据包头解析的程序。它从用户输入中获取一个IP数据包头的字符串,然后将其解析并输出各个字段的信息。

程序首先要求用户输入一个IP数据包头的字符串,然后使用Scanner类获取用户输入的字符串。接着,程序通过替换空格和去除字符串中的空格来处理输入的字符串。

程序接下来开始解析输入的字符串。它首先提取版本号字段,即字符串的第一个字符,并将其转换为十进制数。然后,它提取包头长度字段,即字符串的第二个字符,并将其乘以4得到包头长度的字节数。

接下来,程序提取优先权字段。它将字符串的第三个字符转换为二进制,并取前3位转换为十进制数。然后,根据优先权的值确定TOS字段的具体含义。

程序继续提取IP数据报文总长字段,取字符串的第四到第七个字符,并将其转换为十进制数。然后,它提取标志位字段,取字符串的第八到第十一个字符,并将其转换为十进制数。

接下来,程序提取是否分片字段。它将标志位的第二位进行判断,如果为'0',则表示可以分片,如果为'1',则表示不能分片。然后,程序提取包属于字段,即标志位的第三位进行判断,如果为'0',则表示该包是最后一个分片的包,如果为'1',则表示该包是分片中段的包。最后,程序提取分段偏移字段,即取标志位的第四位到最后一位。

程序继续提取TTL值字段,取字符串的第十七和第十八个字符,并将其转换为十进制数。然后,程序提取协议号字段,取字符串的第十九和第二十个字符,并将其转换为十进制数。根据协议号的值,程序确定协议的名称。

接下来,程序提取头部校验和字段,取字符串的第二十一到第二十四个字符。

然后,程序提取原始地址字段,即将字符串的第二十五到第三十二个字符按照每两个字符转换为十进制数,得到四个数字。

最后,程序提取目标地址字段,即将字符串的第三十三到第四十个字符按照每两个字符转换为十进制数,得到四个数字。

最后,程序输出解析得到的各个字段的信息。

import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        System.out.println('请输入一串IP数据包头:');
        System.out.println();

        Scanner sc = new Scanner(System.in);
        String packet = sc.nextLine().replace(' ', '');
        sc.close();

        // 版本号:取字符串的第一个字符,并将其转换为十进制数。
        int version = Integer.parseInt(packet.substring(0, 1), 16);
        // 包头长度:取字符串的第二个字符(表示包头长度的四分之一),并将其乘以4得到包头长度的字节数。
        int headerLength = Integer.parseInt(packet.substring(1, 2), 16) * 4;

        StringBuilder tmp = new StringBuilder(Integer.toBinaryString(Integer.parseInt(packet.substring(2, 4), 16)));
        int len = tmp.length();
        for (int i = 0; i < 8 - len; i++) {
            tmp.insert(0, '0');
        }

        // 优先权:取字符串的第三个字符的二进制表示的前3位,并将其转换为十进制数。
        int priority = Integer.parseInt(tmp.substring(0, 3), 2);
        // TOS:根据优先权的值确定TOS的具体含义。
        String TOS;
        if (tmp.charAt(3) == '1') {
            TOS = '最小延迟';
        } else if (tmp.charAt(4) == '1') {
            TOS = '最大吞吐量';
        } else if (tmp.charAt(5) == '1') {
            TOS = '最高可靠性';
        } else if (tmp.charAt(6) == '1') {
            TOS = '低成本';
        } else {
            TOS = '一般服务';
        }

        // IP数据报文总长:取字符串的第四到第七个字符,并将其转换为十进制数。
        int packetLength = Integer.parseInt(packet.substring(4, 8), 16);
        // 标志位:取字符串的第八到第十一个字符,并将其转换为十进制数。
        int identification = Integer.parseInt(packet.substring(8, 12), 16);

        tmp = new StringBuilder(Integer.toBinaryString(Integer.parseInt(packet.substring(12, 16), 16)));
        len = tmp.length();
        for (int i = 0; i < 16 - len; i++) {
            tmp.insert(0, '0');
        }
        // 是否分片:根据标志位的第二位判断是否分片。
        String section = tmp.charAt(1) == '0' ? '可以分片' : '不能分片';
        // 包属于:根据标志位的第三位判断包属于哪个分片
        String property = tmp.charAt(2) == '0' ? '最后一个分片的包' : '分片中段的包';
        // 分段偏移:取标志位的第四位到最后一位。
        String fragmentOffset = tmp.substring(3, 16);

        // TTL值:取字符串的第十七和第十八个字符,并将其转换为十进制数。
        int ttl = Integer.parseInt(packet.substring(16, 18), 16);
        // 协议号:取字符串的第十九和第二十个字符,并将其转换为十进制数。然后根据协议号的值,确定协议的名称。
        int protocolCode = Integer.parseInt(packet.substring(18, 20), 16);
        String protocol = '未知';
        for (ProtocolType val : ProtocolType.values()) {
            if (val.getValue() == protocolCode) {
                protocol = val.name();
            }
        }

        tmp = new StringBuilder(Integer.toBinaryString(Integer.parseInt(packet.substring(20, 24), 16)));
        len = tmp.length();
        for (int i = 0; i < 16 - len; i++) {
            tmp.insert(0, '0');
        }
        // 头部校验和:取字符串的第二十一到第二十四个字符
        String checkSum = tmp.toString();
        // 原始地址:将字符串的第二十五到第三十二个字符按照每两个字符转换为十进制数,得到四个数字
        int[] sourceAddress = {
                Integer.parseInt(packet.substring(24, 26), 16),
                Integer.parseInt(packet.substring(26, 28), 16),
                Integer.parseInt(packet.substring(28, 30), 16),
                Integer.parseInt(packet.substring(30, 32), 16)
        };
        // 目标地址:将字符串的第三十三到第四十个字符按照每两个字符转换为十进制数,得到四个数字
        int[] targetAddress = {
                Integer.parseInt(packet.substring(32, 34), 16),
                Integer.parseInt(packet.substring(34, 36), 16),
                Integer.parseInt(packet.substring(36, 38), 16),
                Integer.parseInt(packet.substring(38, 40), 16)
        };

        // 输出包信息
        println('版本号:');
        println(String.valueOf(version));
        System.out.println();

        println('包头长度:');
        println(String.valueOf(headerLength));
        System.out.println();

        println('优先权:');
        println(String.valueOf(priority));
        System.out.println();

        println('TOS:');
        println(TOS);
        System.out.println();

        println('包总长:');
        println(String.valueOf(packetLength));
        System.out.println();

        println('标志位:');
        println(String.valueOf(identification));
        System.out.println();

        println('分片:');
        println(section);
        System.out.println();

        println('包属性:');
        println(property);
        System.out.println();

        println('分段偏移:');
        println(fragmentOffset);
        System.out.println();

        println('TTL:');
        println(String.valueOf(ttl));
        System.out.println();

        println('协议号:');
        println(protocolCode + '(' + protocol + ')');
        System.out.println();

        println('头部校验和:');
        println(checkSum);
        System.out.println();

        println('原始地址:');
        println(sourceAddress[0] + '.' + sourceAddress[1] + '.' + sourceAddress[2] + '.' + sourceAddress[3]);
        System.out.println();

        println('目标地址:');
        println(targetAddress[0] + '.' + targetAddress[1] + '.' + targetAddress[2] + '.' + targetAddress[3]);
        System.out.println();
    }

    static void println(String msg) {
        System.out.printf('% -15s', msg);
    }

    enum ProtocolType {
        ICMP(1),
        IGMP(2),
        TCP(6),
        UDP(17);

        private final int value;

        ProtocolType(int value) {
            this.value = value;
        }

        public int getValue() {
            return value;
        }
    }
}
IP数据包头解析程序:Java代码示例

原文地址: https://www.cveoy.top/t/topic/fkIM 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录