分享

【开源】计算机网络课设-子网划分

落叶 发表于 2020-6-12 19:41:22 [显示全部楼层] 只看大图 回帖奖励 阅读模式 关闭右栏 2 4198
本文内容版权归本人所有,任何人或团体、机构全部转载或者部分转载、摘录,请保留本博客链接或标注来源!

      题目要求:设计一段程序,要求用户输入一个IP地址和一个子网掩码,计算出这个网络的网络位、主机位、网络号(第一个地址)、广播地址、最大主机容纳量、可用起始地址、可用结束地址, 注意要判断用户输入的地址是否有效例如127的环回地址和主机位全为0或者全为1的IP地址。
      附加要求: 要求用户输入一个合理的主机数量,程序对当前地址进行子网划分并输出所有网段和其子网掩码、最大融安主机数量。
      看完了题目要求后我选择使用java来实现,结果截图如下:
B@6KD[8LLB`LX90WGOK@Z`N.png

      那么, 上代码了!
[mw_shl_code=java,true]

package com.company;

import java.math.BigInteger;
import java.sql.PreparedStatement;
import java.util.Scanner;

public class HostTest {
        public static void main(String[] args) {
                //创建储存IP和掩码二进制地址的变量
                BigInteger ip, mask;
                //创建储存IP和掩码的数组
                String[] szIP = new String[4];
                String[] szMask = new String[4];
                //初始化输入器
                Scanner sc = new Scanner(System.in);
                Println("#请输入合法的IPv4地址:");
                try {
                        //从屏幕获取一行用户输入数据
                        String str = sc.nextLine();
                        //将输入的IP地址按.分割为4段
                        String[] tmpIP = str.split("\\.");
                        //如果没有4段就提示错误
                        if (tmpIP.length != 4) throw new Exception();
                        //将获分割的字符串储存到IP数组内
                        for (int i = 0; i < tmpIP.length; i++) szIP = tmpIP;
                } catch (Exception e) {
                        Println("你输入的不是合法的IPv4地址!");
                        return;
                }

                //如果IP为127开头的本地地址则提示错误
                if (szIP[0].equals("127")) {
                        Println("这不是一个有效地址!(127开头的为本地环回地址)");
                        return;
                }

                Println("#请输入合法的子网掩码:");
                try {
                        //从屏幕获取一行用户输入数据
                        String str = sc.nextLine();
                        //将输入的子网掩码按.分割为4段
                        String[] tmpMask = str.split("\\.");
                        //如果没有4段就提示错误
                        if (tmpMask.length != 4) throw new Exception();
                        //将获分割的字符串储存到IP数组内
                        for (int i = 0; i < tmpMask.length; i++) szMask = tmpMask;
                } catch (Exception e) {
                        Println("你输入的不是合法的子网掩码!");
                        return;
                }

                //IP地址位运算
                ip = new BigInteger(Integer.toBinaryString(Integer.parseInt(szIP[0]) << 24), 2);
                ip = ip.add(new BigInteger(Integer.toBinaryString(Integer.parseInt(szIP[1]) << 16), 2));
                ip = ip.add(new BigInteger(Integer.toBinaryString(Integer.parseInt(szIP[2]) << 8), 2));
                ip = ip.add(new BigInteger(Integer.toBinaryString(Integer.parseInt(szIP[3])), 2));

                //子网掩码位运算
                mask = new BigInteger(Integer.toBinaryString(Integer.parseInt(szMask[0]) << 24), 2);
                mask = mask.add(new BigInteger(Integer.toBinaryString(Integer.parseInt(szMask[1]) << 16), 2));
                mask = mask.add(new BigInteger(Integer.toBinaryString(Integer.parseInt(szMask[2]) << 8), 2));
                mask = mask.add(new BigInteger(Integer.toBinaryString(Integer.parseInt(szMask[3])), 2));

                //得到网络位
                int netNum = countStr(mask.toString(2), "1");
                //得到主机位
                int hostNum = 32 - netNum;
                //得到二进制网络位
                String binaryNetAddress = ip.and(mask).toString(2);
                //创建网络号数组
                int[] netAddress = {
                                Integer.parseInt(binaryNetAddress.substring(0, 8), 2),
                                Integer.parseInt(binaryNetAddress.substring(8, 16), 2),
                                Integer.parseInt(binaryNetAddress.substring(16, 24), 2),
                                Integer.parseInt(binaryNetAddress.substring(24, 32), 2)
                };
                //得到二进制网络位并进行判断是否全0或者全1
                String ipNetBits = ip.toString(2).substring(0, netNum);
                if (countStr(ipNetBits, "1") == 0 || countStr(ipNetBits, "1") == 0) {
                        Println("这不是一个有效的IP!(网络位不得全为0或者1)");
                        return;
                }
                //得到最大主机数
                final int MAX_HOSTS = (int) (Math.pow(2, hostNum) - 2);

                //创建网络广播地址数组
                int[] netBroatcastAddress = new int[4];
                netBroatcastAddress[0] = netAddress[0];
                netBroatcastAddress[1] = netAddress[1];
                netBroatcastAddress[2] = netAddress[2];
                netBroatcastAddress[3] = netAddress[3];

                //开始计算网络广播地址
                int tmpNum = MAX_HOSTS + 2 - 1;
                while (tmpNum > 0) {
                        netBroatcastAddress[3]++;
                        tmpNum--;
                        if (netBroatcastAddress[1] > 255) {
                                netBroatcastAddress[0]++;
                                netBroatcastAddress[1] = 0;
                        }
                        if (netBroatcastAddress[2] > 255) {
                                netBroatcastAddress[1]++;
                                netBroatcastAddress[2] = 0;
                        }
                        if (netBroatcastAddress[3] > 255) {
                                netBroatcastAddress[2]++;
                                netBroatcastAddress[3] = 0;
                        }
                }

                //创建主机起始地址数组
                int[] startHostAddress = new int[4];
                startHostAddress[0] = netAddress[0];
                startHostAddress[1] = netAddress[1];
                startHostAddress[2] = netAddress[2];
                startHostAddress[3] = netAddress[3];

                //计算主机开始地址
                boolean carry = true;
                while (carry) {
                        startHostAddress[3]++;
                        if (startHostAddress[3] == 255) {
                                startHostAddress[2]++;
                                startHostAddress[3] = 0;
                                continue;
                        }
                        if (startHostAddress[2] == 255) {
                                startHostAddress[1]++;
                                startHostAddress[2] = 0;
                                continue;
                        }
                        if (startHostAddress[1] == 255) {
                                startHostAddress[0]++;
                                startHostAddress[1] = 0;
                                continue;
                        }
                        carry = false;
                }

                //创建主机结束地址数组
                int[] endHostAddress = new int[4];
                endHostAddress[0] = netBroatcastAddress[0];
                endHostAddress[1] = netBroatcastAddress[1];
                endHostAddress[2] = netBroatcastAddress[2];
                endHostAddress[3] = netBroatcastAddress[3];

                //计算主机结束地址
                carry = true;
                while (carry) {
                        endHostAddress[3]--;
                        if (endHostAddress[3] == 0) {
                                endHostAddress[2]--;
                                endHostAddress[3] = 255;
                                continue;
                        }
                        if (endHostAddress[2] == 0) {
                                endHostAddress[1]--;
                                endHostAddress[2] = 255;
                                continue;
                        }
                        if (endHostAddress[1] == 0) {
                                endHostAddress[0]--;
                                endHostAddress[1] = 255;
                                continue;
                        }
                        carry = false;
                }

                //输出当前地址
                Println(String.format("IP地址:%s.%s.%s.%s", szIP[0], szIP[1], szIP[2], szIP[3]));
                Println(String.format("掩码地址:%s.%s.%s.%s", szMask[0], szMask[1], szMask[2], szMask[3]));
                Println(String.format("网络位:%s", netNum));
                Println(String.format("主机位:%s", hostNum));
                Println(String.format("网络号:%d.%d.%d.%d", netAddress[0], netAddress[1], netAddress[2], netAddress[3]));
                Println(String.format("广播地址:%d.%d.%d.%d", netBroatcastAddress[0], netBroatcastAddress[1], netBroatcastAddress[2], netBroatcastAddress[3]));
                Println(String.format("最大容纳主机:%s", MAX_HOSTS));
                Println(String.format("起始地址:%d.%d.%d.%d", startHostAddress[0], startHostAddress[1], startHostAddress[2], startHostAddress[3]));
                Println(String.format("结束地址:%d.%d.%d.%d\n", endHostAddress[0], endHostAddress[1], endHostAddress[2], endHostAddress[3]));

                Println("请输入有多少台主机需要划分子网(整数):");
                int hosts = sc.nextInt();
                sc.close();

                //计算分配的子网主机位
                int subHostNum = 1;
                while (Math.pow(2, subHostNum) <= hosts) {
                        subHostNum++;
                }
                //当前子网地址数(包括网络号和广播号)
                int subAddressNum = (int) Math.pow(2, subHostNum);
                //拼接二进制子网掩码
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < (32 - subHostNum); i++) sb.append("1");
                for (int i = 0; i < subHostNum; i++) sb.append("0");
                //得到子网掩码
                int[] subMask = {
                                Integer.parseInt(sb.toString().substring(0, 8), 2),
                                Integer.parseInt(sb.toString().substring(8, 16), 2),
                                Integer.parseInt(sb.toString().substring(16, 24), 2),
                                Integer.parseInt(sb.toString().substring(24, 32), 2)
                };
                //当前网络可划分多少个子网
                int subNetNum = (MAX_HOSTS + 2) / subAddressNum;

                //循环输出所有子网段
                int[] subNetAddress = new int[4];
                subNetAddress[0] = netAddress[0];
                subNetAddress[1] = netAddress[1];
                subNetAddress[2] = netAddress[2];
                subNetAddress[3] = netAddress[3];

                for (int i = 0; i < subNetNum; i++) {
                        System.out.println(String.format("[子网编号%d]%d.%d.%d.%d 掩码:%d.%d.%d.%d 最大容纳%d台主机", i,
                                        subNetAddress[0], subNetAddress[1], subNetAddress[2], subNetAddress[3],
                                        subMask[0], subMask[1], subMask[2], subMask[3], (subAddressNum-2)));

                        for(int j =0; j < (subAddressNum-1); j++) {
                                carry = true;
                                while (carry) {
                                        subNetAddress[3]++;
                                        if (subNetAddress[3] == 256) {
                                                subNetAddress[2]++;
                                                subNetAddress[3] = 0;
                                                continue;
                                        }
                                        if (subNetAddress[2] == 256) {
                                                subNetAddress[1]++;
                                                subNetAddress[2] = 0;
                                                continue;
                                        }
                                        if (subNetAddress[1] == 256) {
                                                subNetAddress[0]++;
                                                subNetAddress[1] = 0;
                                                continue;
                                        }
                                        carry = false;
                                }
                        }
                        subNetAddress[3]++;
                        if (subNetAddress[3] == 256) {
                                subNetAddress[2]++;
                                subNetAddress[3] = 0;
                        }
                }
        }

        /*
         * 替换System.out.println()函数
         * */
        static void Println(String msg) {
                System.out.println(msg);
        }

        /*
         * 查找字符串中某个字符串出现的次数
         * str: 被查找的字符串
         * sToFind: 查找的字符串
         * */
        static int countStr(String str, String sToFind) {
                int num = 0;
                while (str.contains(sToFind)) {
                        str = str.substring(str.indexOf(sToFind) + sToFind.length());
                        num++;
                }
                return num;
        }
}
[/mw_shl_code]
Felix
2020年6月12日 19:40
回复

使用道具 举报

已有(2)人评论

跳转到指定楼层
落叶 发表于 2020-6-12 19:44:34
IzayoiFly 发表于 2020-6-12 11:43
草…大学学的忘完了

回复

使用道具 举报

IzayoiFly 发表于 2020-6-12 19:43:22
草…大学学的忘完了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则