import java.util.Scanner; \npublic class Main { \n\tpublic static void main(String[] args) { \n\t System.out.println("请输入一串IP数据包头:"); \n\t System.out.println(); \n\n\t Scanner sc = new Scanner(System.in); \n\t String packet = sc.nextLine().replace(" ", ""); \n\t sc.close(); \n\n\t // 版本号 \n\t int version = Integer.parseInt(packet.substring(0, 1), 16); \n\t // 包头长度 \n\t int headerLength = Integer.parseInt(packet.substring(1, 2), 16) * 4; \n\n\t StringBuilder tmp = new StringBuilder(Integer.toBinaryString(Integer.parseInt(packet.substring(2, 4), 16))); \n\t int len = tmp.length(); \n\t for (int i = 0; i < 8 - len; i++) { \n\t tmp.insert(0, "0"); \n\t } \n\n\t // 优先权 \n\t int priority = Integer.parseInt(tmp.substring(0, 3), 2); \n\t // TOS \n\t String TOS; \n\t if (tmp.charAt(3) == '1') { \n\t TOS = "最小延迟"; \n\t } else if (tmp.charAt(4) == '1') { \n\t TOS = "最大吞吐量"; \n\t } else if (tmp.charAt(5) == '1') { \n\t TOS = "最高可靠性"; \n\t } else if (tmp.charAt(6) == '1') { \n\t TOS = "低成本"; \n\t } else { \n\t TOS = "一般服务"; \n\t } \n\n\t // IP数据报文总长(包含头部和数据) \n\t int packetLength = Integer.parseInt(packet.substring(4, 8), 16); \n\t // 标志位 \n\t int identification = Integer.parseInt(packet.substring(8, 12), 16); \n\n\t tmp = new StringBuilder(Integer.toBinaryString(Integer.parseInt(packet.substring(12, 16), 16))); \n\t len = tmp.length(); \n\t for (int i = 0; i < 16 - len; i++) { \n\t tmp.insert(0, "0"); \n\t } \n\t // 是否分片 \n\t String section = tmp.charAt(1) == '0' ? "可以分片" : "不能分片"; \n\t // 包属于 \n\t String property = tmp.charAt(2) == '0' ? "最后一个分片的包" : "分片中段的包"; \n\t // 分段偏移 \n\t String fragmentOffset = tmp.substring(3, 16); \n\n\t // TTL值 \n\t int ttl = Integer.parseInt(packet.substring(16, 18), 16); \n\t // 协议号 \n\t int protocolCode = Integer.parseInt(packet.substring(18, 20), 16); \n\t String protocol = "未知"; \n\t for (ProtocolType val : ProtocolType.values()) { \n\t if (val.getValue() == protocolCode) { \n\t protocol = val.name(); \n\t } \n\t } \n\n\t tmp = new StringBuilder(Integer.toBinaryString(Integer.parseInt(packet.substring(20, 24), 16))); \n\t len = tmp.length(); \n\t for (int i = 0; i < 16 - len; i++) { \n\t tmp.insert(0, "0"); \n\t } \n\t // 头部校验和 \n\t String checkSum = tmp.toString(); \n\t // 原始地址 \n\t int[] sourceAddress = { \n\t Integer.parseInt(packet.substring(24, 26), 16), \n\t Integer.parseInt(packet.substring(26, 28), 16), \n\t Integer.parseInt(packet.substring(28, 30), 16), \n\t Integer.parseInt(packet.substring(30, 32), 16) \n\t }; \n\t // 目标地址 \n\t int[] targetAddress = { \n\t Integer.parseInt(packet.substring(32, 34), 16), \n\t Integer.parseInt(packet.substring(34, 36), 16), \n\t Integer.parseInt(packet.substring(36, 38), 16), \n\t Integer.parseInt(packet.substring(38, 40), 16) \n\t }; \n\n\t // 输出包信息 \n\t println("版本号:"); \n\t println(String.valueOf(version)); \n\t System.out.println(); \n\n\t println("包头长度:"); \n\t println(String.valueOf(headerLength)); \n\t System.out.println(); \n\n\t println("优先权:"); \n\t println(String.valueOf(priority)); \n\t System.out.println(); \n\n\t println("TOS:"); \n\t println(TOS); \n\t System.out.println(); \n\n\t println("包总长:"); \n\t println(String.valueOf(packetLength)); \n\t System.out.println(); \n\n\t println("标志位:"); \n\t println(String.valueOf(identification)); \n\t System.out.println(); \n\n\t println("分片:"); \n\t println(section); \n\t System.out.println(); \n\n\t println("包属性:"); \n\t println(property); \n\t System.out.println(); \n\n\t println("分段偏移:"); \n\t println(fragmentOffset); \n\t System.out.println(); \n\n\t println("TTL:"); \n\t println(String.valueOf(ttl)); \n\t System.out.println(); \n\n\t println("协议号:"); \n\t println(protocolCode + "(" + protocol + ")"); \n\t System.out.println(); \n\n\t println("头部校验和:"); \n\t println(checkSum); \n\t System.out.println(); \n\n\t println("原始地址:"); \n\t println(sourceAddress[0] + "." + sourceAddress[1] + "." + sourceAddress[2] + "." + sourceAddress[3]); \n\t System.out.println(); \n\n\t println("目标地址:"); \n\t println(targetAddress[0] + "." + targetAddress[1] + "." + targetAddress[2] + "." + targetAddress[3]); \n\t System.out.println(); \n\t} \n\n\tstatic void println(String msg) { \n\t System.out.printf("%-15s", msg); \n\t} \n\n\tenum ProtocolType { \n\t ICMP(1), \n\t IGMP(2), \n\t TCP(6), \n\t UDP(17); \n\n\t private final int value; \n\n\t ProtocolType(int value) { \n\t this.value = value; \n\t } \n\n\t public int getValue() { \n\t return value; \n\t } \n\t} \n}程序解释内容:该程序用于解析输入的IP数据包头,并输出各个字段的值。 \n\n首先,程序会提示用户输入一串IP数据包头。用户输入的字符串中可以包含空格,但程序会将空格删除。 \n\n然后,程序会将输入的字符串拆分为各个字段,并依次解析每个字段的值。 \n\n以下是程序中各个字段的解析过程: \n\n1. 版本号:取字符串的第一个字符,并将其转换为十进制数。 \n\n2. 包头长度:取字符串的第二个字符(表示包头长度的四分之一),并将其乘以4得到包头长度的字节数。 \n\n3. 优先权:取字符串的第三个字符的二进制表示的前3位,并将其转换为十进制数。 \n\n4. TOS:根据优先权的值确定TOS的具体含义。 \n\n5. IP数据报文总长:取字符串的第四到第七个字符,并将其转换为十进制数。 \n\n6. 标志位:取字符串的第八到第十一个字符,并将其转换为十进制数。 \n\n7. 是否分片:根据标志位的第二位判断是否分片。 \n\n8. 包属于:根据标志位的第三位判断包属于哪个分片。 \n\n9. 分段偏移:取标志位的第四位到最后一位。 \n\n10. TTL值:取字符串的第十七和第十八个字符,并将其转换为十进制数。 \n\n11. 协议号:取字符串的第十九和第二十个字符,并将其转换为十进制数。然后根据协议号的值,确定协议的名称。 \n\n12. 头部校验和:取字符串的第二十一到第二十四个字符。 \n\n13. 原始地址:将字符串的第二十五到第三十二个字符按照每两个字符转换为十进制数,得到四个数字。 \n\n14. 目标地址:将字符串的第三十三到第四十个字符按照每两个字符转换为十进制数,得到四个数字。 \n\n最后,程序会输出每个字段的名称和值。 \n\n注意:该程序假设输入的IP数据包头是符合规范的,并且没有错误。如果输入的数据包头不符合规范,程序可能会出现异常。

IP数据包头解析器:Java代码示例及解析

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

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