简单的端口扫描程序(操作系统课程设计)

 题目:

课题内容10、编写一个简单的端口扫描程序

目的:熟悉Linux/Windows下socket、网络编程的基本方法;

任务:编写一个简单的程序,该程序可扫描局域网的某计算机开放了哪些端口

思考路线及实现

首先我们需要知道,如何完成一个简单的端口扫描系统?

在Java程序中,创建java.net.Socket包中的Socket,填入连接IP地址和端口,若抛出IOException错误,则表示连接失败,若IP地址无误,就是端口没开放。

          System.out.print("输入你需要扫描的host:");
          Scanner scanner = new Scanner(System.in);
          String s = scanner.nextLine();
          for (int i = 1; i <= 100; i++)
          {
              try
              {
                  Socket socket = new Socket(s, i);
                  socket.close();
                  System.out.println("host:"+s+ " port: "+i+" is open");

              }catch (IOException e)
              {
                  System.out.println("host:"+s+ " port: "+i+" is close");
              }
          }
优化方案

根据网上别人写的端口扫描,学到通过InetSocketAddress类进行连接,这时候,不会对每个IP和端口真正的连接,而是使用“探测”的方式,设置超时时间为200ms,这样速度能提升很多(特别是扫描本机以外的IP地址)。

代码实现:

          System.out.print("输入你需要扫描的host:");
          Scanner scanner = new Scanner(System.in);
          String s = scanner.nextLine();
          for (int i = 1; i <= 100; i++)
          {
              try
              {
                  Socket socket = new Socket();
                  socket.connect(new InetSocketAddress(s,i),200);
                  socket.close();
                  System.out.println("host:"+s+ " port: "+i+" is open");
              }catch (IOException e)
              {
                  System.out.println("host:"+s+ " port: "+i+" is close");
              }
          }
使用多线程优化

本次优化使用线程池,首先创建一个多线程类,实现Runnable接口。

public class CSDNRunnable implements Runnable{
    public String host;

    public int port;

    public CSDNRunnable(String host, int port) {
        this.host = host;
        this.port = port;
    }

    @Override
    public void run() {
        if (TCPisPortOpen(host,port))
        {
            String message = "Port " + port + " is open";
            System.out.println(message);
        }
        else
        {
            String message = "Port " + port + " is closed";
            System.out.println(message);
        }
    }


    private static boolean TCPisPortOpen(String host, int port) {
        try {
            // 创建Socket并尝试连接
            Socket socket = new Socket();
            socket.connect(new InetSocketAddress(host, port), 200); // 200毫秒超时
            socket.close();
            return true;
        } catch (IOException e) {
            return false;
        }
    }
}

之后使用线程池实现

        //创建线程池
        ExecutorService service = Executors.newFixedThreadPool(10);//开启多少线程
        ThreadPoolExecutor service1 = (ThreadPoolExecutor) service;
        //设置线程池属性
        service1.setMaximumPoolSize(500);//设置线程池中线程数的上限

        for (int port = 1; port <= 100; port++) {
            service.execute(new CSDNRunnable("127.0.0.1",port));
        }
        System.out.println("成功调用");
        //关闭线程池
        service.shutdown();

配合web使用

首先规划好自己想要的效果:我想要把扫描结果实时显示出来,这样对于用户体验感也好。基于这个需求我web需要一个框填写需要扫描的信息,一个框显示扫描结果的信息。这样一个大框架就想象出来了。

简单的web设计:

相关代码:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>扫描端口程序</title>
    <script src="../static/js/axios.js"></script>
    <style>
        .box{
               position: absolute;
               width: 600px;
               height: 400px;
               top: 100px;
               left: 150px;
               background-color: aquamarine;
               text-align: center;
               z-index: 10;
        }
        .result{
            position: absolute;
            width: 600px;
            height: 400px;
            top: 100px;
            right: 150px;
            background-color: blanchedalmond;
            text-align: center;
            overflow-y: scroll;
            z-index: 1;
        }
        .textOpen{
            color: green;
        }
        .textClose{
            color: red;
        }

        .select-box {
            position: absolute;
            top: 60px;
            right: 150px;
        }
        .show-box {
            position: absolute;
            top: 60px;
            right: 475px;
        }
        .error{
            border: 2px solid red;
        }
        .error-host-text{
            position: absolute;
            top: 85px;
            left: 153px;
            color: red;
        }
        .error-thread-text{
            position: absolute;
            top: 150px;
            left: 153px;
            color: red;
        }
        .error-FPort-text{
            position: absolute;
            top: 215px;
            left: 136px;
            color: red;
        }
        .error-LPort-text{
            position: absolute;
            top: 279px;
            left: 70px;
            color: red;
        }
        .error-Link-text{
            position: absolute;
            top: 370px;
            left: 160px;
            color: red;
        }

    </style>
</head>

<body>
   <script>
   var total = []
   var isOKHost = 0
   var isOKThread = 0
   var isOKFPort = 0
   var isOKLPort = 0
   var isOKLink = 0

   let LTo;
       const startLink = ()=>
       {
           //获取button按钮并改变
           document.getElementById("link_button").disabled = true;
           document.getElementById("link_button").innerHTML = "已经连接";

           //获取result_box,以便添加html
           const resultBox = document.getElementById("result");
           //建立socket连接
           const socket = new WebSocket("ws://localhost:8080/portScan")
           //当连接成功时调用的方法
           socket.onopen = () => {
               window.alert("WebSocket连接已打开")
               isOKLink = 1;
           };
           //监听信息时的方法
           socket.onmessage = (event) => {
               console.log("收到消息:", event.data);
                   const isOpen = event.data.split(" ");
                   //加入数组
                   total[isOpen[1]] = event.data
                   //创建一个div
                   const newDiv = document.createElement("div");
                   newDiv.innerHTML = event.data + "<br/>"

                   if (isOpen[3] === 'closed') {
                       newDiv.className = "textClose";
                   } else {
                       newDiv.className = "textOpen";
                   }
                   resultBox.appendChild(newDiv);
               console.log("LTo = "+LTo + " total= "+total.length)
               if (LTo === total.length)
               {
                   document.getElementById("start_button").disabled = false;
                   document.getElementById("start_button").innerHTML = "点击开始";
                   alert("扫描完成")
               }

           };
           //关闭连接时调用的方法
           socket.onclose = (event) => {
               console.log("WebSocket连接已关闭", event);
           };
           //连接出错时调用的方法
           socket.onerror = (error) => {
               console.error("WebSocket错误:", error);
           };
       }


       //开始扫描
      const scanstart = ()=>{
          //获取用户输入信息
          const host = document.querySelector('input[name="host"]').value;
          const thread = document.querySelector('input[name="thread"]').value;
          const FPort = document.querySelector('input[name="FPort"]').value;
          const LPort = document.querySelector('input[name="LPort"]').value;
          //检查所有的输入数是否合法
          if ( isOKLink !==1 && isOKHost !==1 && isOKThread !==1 && isOKLPort !== 1 && isOKFPort !== 1)
          {
              //拒绝发出请求并进行提示
              const box = document.getElementById("box")
              //创建一个div
              const newDiv = document.createElement("div");
              newDiv.innerHTML = "您尚未连接或数据输入错误,请检查重来"
              newDiv.className = "error-Link-text"
              newDiv.id = "error-Link-text"
              box.appendChild(newDiv);
          }
          else {
              if (document.getElementById("error-Link-text") !==null) {
                  //先清空错误提示
                  const errorLink = document.getElementById("error-Link-text")
                  errorLink.innerHTML = ""
              }
              LTo = parseInt(LPort)
              //先清空resultBox
              const resultBox = document.getElementById("result");
              resultBox.innerHTML = "";
              //获取用户选择什么模式
              const type = document.getElementById("options").value;
              //清空结果数组
              total.length = 0;
              //将按钮设置为正在获取
              //获取button按钮并设置为不可用
              document.getElementById("start_button").disabled = true;
              document.getElementById("start_button").innerHTML = "正在查询";
              //发送请求获取
              var xhr = new XMLHttpRequest();
              //设置请求方法和URL
              var url = "http://localhost:8080/scan/" + host + "/" + FPort + "/" + LPort + "/" + type + "/" + thread;
              xhr.open('GET', url);
              // 发送请求
              xhr.send();
              //设置请求完成后的回调函数
              xhr.onreadystatechange = function () {
                  if (xhr.status >= 200 && xhr.status < 300) {
                      // 请求成功,处理响应数据
                      //获取button按钮并设置为不可用

                  } else {
                      // 请求失败,处理错误
                      alert('API请求失败,状态码:' + xhr.status);
                  }
              };
          }
      }

      //开始查找,因为数据有序且数据量不大,使用二分查找
      const selectPort = ()=>{
          //获取input的值
          const StringSelectValue = document.querySelector('input[name="select-resultBox"]').value;
          const selectValue = parseInt(StringSelectValue)

          //使用二分查找法查数组
          let left = 0;
          let right = total.length-1;
          console.log("right="+right)
          while(left <= right)
          {
              const mid = Math.floor((left + right) / 2);
              console.log("mid="+mid)
              //处理数组
              const SignTotal = total[mid].split(" ");
              const StringPort = SignTotal[1]
              const port = parseInt(StringPort)

              console.log("left="+left+"  mid="+mid+"  right="+right+"  port="+port + "  selectValue="+ selectValue)
              if (port === selectValue)
              {
                  //清空box
                  const resultBox = document.getElementById("select-showBox");
                  resultBox.innerHTML = "";
                  //创建新的div
                  //创建一个div
                  const newDiv = document.createElement("div");
                  newDiv.innerHTML = total[mid]
                  if (SignTotal[3] === 'closed')
                  {
                      newDiv.className = "textClose";
                  }
                  else
                  {
                      newDiv.className = "textOpen";
                  }
                  resultBox.appendChild(newDiv);
                  return
              }
              else if (port < selectValue)
              {
                  left = mid + 1;
              }
              else
              {
                  right = mid - 1;
              }
          }
          //查找失败
          alert("查找失败,您扫描的范围和条件可能不包含该端口")
      }

      //开始排序
   const sortList = ()=>{
      //首先清空
       const resultBox = document.getElementById("result");
       resultBox.innerHTML = "";
       //遍历数组
       for (let i = 1; i <total.length; i++)
       {
           //分解
           const type = total[i].split(" ")[3]

           const newDiv = document.createElement("div");
           newDiv.innerHTML = total[i];
           if (type === 'closed')
           {
               newDiv.className = "textClose";
           }
           else
           {
               newDiv.className = "textOpen";
           }
           resultBox.appendChild(newDiv);
       }
       alert("排序完成")
   }


   //开始验证
   //验证域名
   function isHost(){
       const host = document.querySelector('input[name="host"]').value;
       // 定义IP地址和域名的正则表达式
       var ipRegex = /^(\d{1,3}\.){3}\d{1,3}$/;
       var domainRegex = /^[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
       // 验证输入值
       var isValid = ipRegex.test(host) || domainRegex.test(host);
       var inputField = document.getElementById("host")
       var box = document.getElementById("box")
       if (isValid) {
           inputField.classList.remove('error');
           const errorHost = document.getElementById("error-host-text")
           errorHost.innerHTML = ""
           isOKHost =1
       } else {
           inputField.classList.add('error');
           //创建一个div
           const newDiv = document.createElement("div");
           newDiv.innerHTML = "您的ip地址或域名输入错误,请重新输入"
           newDiv.className = "error-host-text"
           newDiv.id = "error-host-text"
           box.appendChild(newDiv);
           isOKHost = 0
       }
   }

   //验证线程输入值是否合法
   function isThread(){
       const thread = document.querySelector('input[name="thread"]').value;
       //将输入值转化为数字
       var numberValue = parseInt(thread);
       //指定最大值
       var max = 500;
       //验证输入值是否是数字且大于0,小于max
       var isValid = !isNaN(numberValue) && numberValue > 0 && numberValue < max;
       var inputField = document.getElementById("thread")
       var box = document.getElementById("box")

       if (isValid) {
           inputField.classList.remove('error');
           const errorThread = document.getElementById("error-thread-text")
           errorThread.innerHTML = ""
           isOKThread = 1
       } else {
           inputField.classList.add('error');
           //创建一个div
           const newDiv = document.createElement("div");
           newDiv.innerHTML = "您输入的线程不合规定,请重新输入"
           newDiv.className = "error-thread-text"
           newDiv.id = "error-thread-text"
           box.appendChild(newDiv);
           isOKThread = 0
       }

   }

   //验证端口输入值是否合法
   function isFPort(){
       const FPort = document.querySelector('input[name="FPort"]').value;

       //转换成数字
       var portNumber = parseInt(FPort);

       //验证是否是数字且在合法范围内
       var isValid = !isNaN(portNumber) && portNumber >=0 && portNumber <=65535

       //验证
       var inputField = document.getElementById("FPort")
       var box = document.getElementById("box")

       if (isValid) {
           inputField.classList.remove('error');
           const errorFPort = document.getElementById("error-FPort-text")
           errorFPort.innerHTML = ""
           isOKFPort = 1
       } else {
           inputField.classList.add('error');
           //创建一个div
           const newDiv = document.createElement("div");
           newDiv.innerHTML = "您输入的端口不合规定,请重新输入(0~65535)"
           newDiv.className = "error-FPort-text"
           newDiv.id = "error-FPort-text"
           box.appendChild(newDiv);
           isOKFPort = 0
       }


   }

   //验证端口输入值是否合法
   function isLPort(){
       const FPort = document.querySelector('input[name="FPort"]').value;
       const LPort = document.querySelector('input[name="LPort"]').value;

       //两个变成数字
       var FPortNum = parseInt(FPort)
       var LPortNum = parseInt(LPort)

       //验证是否是数字,是否合法且大于等于开始端口
       var isValid = !isNaN(FPortNum) && !isNaN(LPortNum) && LPortNum >=0 && LPortNum <=65535 && LPortNum>=FPortNum
       //验证
       var inputField = document.getElementById("LPort")
       var box = document.getElementById("box")

       if (isValid) {
           inputField.classList.remove('error');
           const errorLPort = document.getElementById("error-LPort-text")
           errorLPort.innerHTML = ""
           isOKLPort = 1

       } else {
           inputField.classList.add('error');
           //创建一个div
           const newDiv = document.createElement("div");
           newDiv.innerHTML = "您输入的端口不合规定,请重新输入(0~65535且大于等于开始端口)"
           newDiv.className = "error-LPort-text"
           newDiv.id = "error-LPort-text"
           box.appendChild(newDiv);
           isOKLPort = 0
       }
   }

   </script>
<div class="box" id="box">
    <br/>
    <br/>
    请输入需要扫描端口的ip地址(本地为localhost)
    <br/>
   <input type="text" id="host" name= "host" placeholder="需要监听的ip地址" onblur="isHost()"/>
    <br/>
    <br/>
    请输入需要开启多少线程进行扫描(最大不超过500个)
    <br/>
   <input type="text" id="thread" name= "thread" value="1" placeholder="输入开启多少线程" onblur="isThread()"/>
    <br/>
    <br/>
    请输入从哪个端口开始扫描
    <br/>
    <input type="text" id="FPort" name= "FPort" placeholder="输入开始端口" onblur="isFPort()"/>
    <br/>
    <br/>
    请输入到哪个端口结束扫描
    <br/>
    <input type="text" id="LPort" name= "LPort" placeholder="输入结束端口" onblur="isLPort()"/>
    <br/>
    <br/>
    <label for="options">请选择一个显示选项</label>
    <select id="options" name="options">
        <option value="All" selected>显示所有端口</option>
        <option value="open">显示开启端口</option>
        <option value="close">显示关闭端口</option>
    </select>
    <br/>
    <br/>
    <button id="link_button" type="button" onclick="startLink()">点击连接</button>
    <button id="start_button"  type="button" onclick="scanstart()">点击开始</button>

</div>
<div class="select-box">
    <input type="text" name="select-resultBox" id="select-resultBox" placeholder="请输入查询的端口号">
    <button type="button" id="select-button" onclick="selectPort()">点击查询</button>
    <button type="button" id="sort-button" onclick="sortList()">点击排序</button>
</div>
   <div id="select-showBox" class="show-box"></div>
<div class="result" id="result">

</div>

</body>
</html>

通过HTML我们可以看到,我们这次使用websocket进行实现,接下来我们进行websocket的实现(关于这个已经有很多博客有很详细的回答了,这里就不赘述了)。

首先导入依赖:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>

进行配置

@Configuration
public class webSocketConfig {

    @Bean
    public ServerEndpointExporter serverEndpointExporter(){
        return new ServerEndpointExporter();
    }

}

写webSocket类,因为这是个面对老师演示的课程设计,所以所有扫描信息直接对所有用户进行广播。


@ServerEndpoint(value = "/portScan")
@Component
public class ScannerController {
    /**
     * 类的日志
     */
    private static final Logger log = LoggerFactory.getLogger(ScannerController.class);

    /**
     * 为记录用户
     */
    private static final CopyOnWriteArrayList<Session> sessions = new CopyOnWriteArrayList<>();

    /**
     * 成功建立连接调用的方法
     * */
    @OnOpen
     public void onOpen(Session session
                        ) {
         sessions.add(session);
         log.info(session.getId()+"开启连接");
     }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(Session session)
    {
        sessions.remove(session);
        log.info(session.getId()+"关闭连接");
    }
    
    //接收到信息时对所有用户进行广播
    public static synchronized void broadcast(String message) {
        for (Session session : sessions) {
            if (session.isOpen()) {
                try {
                    session.getBasicRemote().sendText(message);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

 最后写controller,说实话这个接口写的不优雅。

@RestController
public class MainController {

    /**
     * 获取host里的FPort-LPort端口所有状态
     * @param host
     * @param FPort
     * @param LPort
     * @return
     */
    @GetMapping("/scan/{host}/{FPort}/{LPort}/{type}/{thread}")
    public String Scan(@PathVariable("host")  String host,
                       @PathVariable("FPort") String FPort,
                       @PathVariable("LPort") String LPort,
                       @PathVariable("type")  String type,
                       @PathVariable("thread") String thread) {
        int startPort = Integer.parseInt(FPort);
        int endPort = Integer.parseInt(LPort);
        int threads = Integer.parseInt(thread);
        //创建线程池
        ExecutorService service = Executors.newFixedThreadPool(threads);
        ThreadPoolExecutor service1 = (ThreadPoolExecutor) service;
        //设置线程池属性
        service1.setMaximumPoolSize(500);//设置线程池中线程数的上限

        for (int port = startPort; port <= endPort; port++) {
            service.execute(new RunnableTest(host,port,type));
        }
        System.out.println("成功调用");
        //关闭线程池
        service.shutdown();
        return "请求成功";
    }
}

这样就完成了,最后我会上传我的实验源码。

https://download.csdn.net/download/weixin_59915237/88979124?spm=1001.2014.3001.5501

本文基于作者自身的学习总结。如有错误,恳请指出。 如果对您有帮助的话,请给我点个赞吧。作者在后面也会分享文章,要是感兴趣也可以给我点个关注。

  • 20
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
端口扫描软件的代码在网上很多,可是并不一定适合基础不深的鸟鸟们学。要不就是代码大多都很长而且使用了多线程(关于多线程的很多概念就够闹腾的了,扫描部分就更算了),让我等小菜都望而生畏;要不就是速度很慢,学会了也派不上用场。今天我就介绍一下自己学习winsock后写的端口扫描软件吧! 端口扫描软件的基本思路就不说了,没有什么很难的算法,大家想想就应该知道的,只要从起始端口到结尾端口都遍历一遍,找到打开的端口输出就可以了。大体的就是这个样子:for(CurrPort=StartPort;CurrPort<=EndPort;CurrPort++) {scan的执行体; }。这个软件没有使用到多线程技术,也就不用考虑那么多的关于多线程的概念了。因此我们的这个扫描软件从两个方面来讨论,第一方面是如何可以找到打开的端口,第二方面是如何提高扫描端口的速度。 一、找到打开的端口 在介绍如何找到打开的端口以前,让我们先来认识一个函数——connect()。connect函数将一个流套接字连接到指定IP地址的指定端口上。connect函数的用法:int connect(SOCKET s,const struct sockaddr FAR* name,int namelen);参数s指定用于连接的套接字句柄,name参数指向一个sockaddr_in结构,用来指定要连接到的服务器的IP地址和端口,namelen参数则指定sockaddr_in结构的长度。这个参数连接成功的时候,函数返回0,否则返回值是SOCKET_ERROR。connect函数的用法大体我们就说这么多了。说到这里大家应该想到了吧?我们用connect函数的返回值进行判断,找到打开的端口号。好,看下具体的代码,有详细的注释,如果对函数不明白可以到MSDN或网上查询。 int scan(char *Ip, int StartPort, int EndPort) { clock_t StartTime,EndTime; //扫描的开始时间和结束时间 float CostTime; //扫描过程中耗费的时间 WSADATA wsa; SOCKET s; struct sockaddr_in server; int CurrPort; //当前端口 int ret; WSAStartup(MAKEWORD(2,2),&wsa); //使用winsock函数之前,必须用WSAStartup函数来装入并初始化动态连接库 server.sin_family=AF_INET; //指定地址格式,在winsock中只能使用AF_INET server.sin_addr.s_addr=inet_addr(Ip); //指定被扫描的IP地址 StartTime=clock(); for(CurrPort=StartPort;CurrPort<=EndPort;CurrPort++) { s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); //创建套接字 /* SOCKET socket(int af,int type,int protocol); 为通信连接创建一个套接字 af参数: 指定套接字地址格式,在winsock中只能使用AF_INET type参数: 套接字类型,这里使用了SOCK_STREAM,流套接字 protocol参数:配合type使用,指定协议类型,这里使用IPPROTO_TCP(就是TCP协议) */ server.sin_port=htons(CurrPort); //指定被扫描IP地址的端口号 ret=connect(s,(struct sockaddr *)&server,sizeof(server)); //连接 if(0==ret) //判断连接是否成功 { printf("%s:%d\n",Ip,CurrPort); closesocket(s); } } EndTime=clock(); CostTime=(float)(EndTime-StartTime)/CLOCKS_PER_SEC; printf("Cost time:%f second\n",CostTime); //输出扫描过程中耗费的时间 WSACleanup(); //释放动态连接库并释放被创建的套接字 return 1; }
### 回答1: 系统端口扫描是网络安全相关领域内的一个比较重要的技术,其作用是对计算机系统进行全面的检测,从而发现系统中可能存在的漏洞或安全隐患。本文将介绍我所设计的一款系统端口扫描程序,它是基于Java语言开发的,具有高效、可靠的特点。 首先,我的程序可以快速、准确地扫描指定IP地址的端口,并生成端口号和端口状态的报告。程序的主要功能包括三个方面:扫描单个端口、扫描一段端口范围、扫描所有端口。用户可以根据自己的需要来选择相应的功能。同时,程序支持多线程的方式进行扫描,从而提高了扫描效率。 其次,我的程序针对常见的网络攻击方式进行了优化,比如SYN Flood等攻击方式。程序能够自动识别这些攻击方式并及时报警,从而避免了系统遭受攻击。 最后,我的程序考虑到了用户友好性的因素,采用了简洁明了的界面,同时提供了详细的用户帮助文档,从而方便了用户的操作。 总之,我的系统端口扫描程序设计了一套完备的解决方案,具有高效、可靠、安全、易用等多方面的优点,适用于各种规模的网络系统,可以为用户提供全面的安全保障。 ### 回答2: 系统端口扫描课程设计 Java 系统端口扫描是计算机网络中重要的操作,也是网络安全领域中的必备技能之一。本文将介绍如何使用 Java 编程语言来实现一个简单的系统端口扫描程序。 简介 端口是计算机系统网络通讯中最基本的单位,它负责建立网络连接、传输数据等功能。常用的计算机端口有 0~65535 个,其中 1~1023 个是被默认分配为标准端口使用。通过扫描端口,我们可以了解到目标主机上运行着哪些服务,从而更有针对性的进行安全检查。 实现步骤 1. 定义端口列表 首先我们需要定义一张端口列表,包含了我们要扫描的所有端口。可以使用 Java 中的数组来实现,示例代码如下: ```java int[] portList = {21, 22, 23, 25, 53, 80, 110, 143, 443, 3306}; ``` 2. 遍历端口列表 定义好端口列表之后,我们需要遍历列表中的所有端口,并检查这些端口是否处于开放状态。可以使用 Java 中的 for 循环来遍历端口列表,代码示例如下: ```java for (int port : portList) { //检查端口状态 } ``` 3. 检查端口状态 在遍历端口列表的同时,我们需要检查每个端口的开放状态。可以使用 Java 的 Socket 类来实现。代码示例如下: ```java Socket socket = null; try { socket = new Socket(host, port); //端口开放 } catch (IOException e) { //端口关闭 } finally { if (socket != null) { try { socket.close(); } catch (IOException e) {} } } ``` 在代码中,我们首先尝试连接目标主机的指定端口,如果连接成功,则说明该端口处于开放状态;如果连接失败,则说明该端口处于关闭状态。 4. 整合代码 将以上三步操作整合起来,即可实现一个简单的系统端口扫描程序。代码示例如下: ```java import java.io.IOException; import java.net.Socket; public class PortScanner { public static void main(String[] args) { //目标主机 IP String host = "localhost"; //端口列表 int[] portList = {21, 22, 23, 25, 53, 80, 110, 143, 443, 3306}; //遍历端口列表,检查端口状态 for (int port : portList) { Socket socket = null; try { socket = new Socket(host, port); //端口开放 System.out.println(port + " open"); } catch (IOException e) { //端口关闭 System.out.println(port + " closed"); } finally { if (socket != null) { try { socket.close(); } catch (IOException e) {} } } } } } ``` 总结 通过以上简单的代码实现,我们可以自己编写一个系统端口扫描程序。当然,在实际的安全检查中,通常需要更加完善和专业的工具来完成复杂的操作。希望读者在学习完本文之后,能够对系统端口扫描有更加深入的了解。 ### 回答3: 系统端口扫描是网络安全领域非常重要的一个主题,它能够帮助我们发现网络系统是否存在安全漏洞,进而采取相应措施进行加固。为了学习和深入理解系统端口扫描的原理和过程,我进行了一个课程设计,使用Java语言进行编写。 首先,我定义了一个TCP端口扫描的接口,里面包括了一些方法,例如设置扫描的主机IP地址、定义扫描的端口范围、启动扫描等。然后使用Java的多线程机制,实现了并发的端口扫描,加快了扫描的速度。 在代码的实现过程中,定义了一个Socket对象,用于与主机建立连接,通过检测是否抛出异常来判断是否开放了该端口。同时,为了提高扫描的效率,设置了超时时间,当连接的时间超过超时时间时,会自动断开连接。 除此之外,还实现了一个简单的用户界面,让用户可以进行设置扫描的目标主机和端口范围,同时还能够实时显示扫描的进度和结果。为了方便用户对扫描结果的分析,还将结果以表格形式进行展示,包括IP地址、开放的端口号等信息。 综上所述,我的系统端口扫描课程设计使用了Java语言进行编写,实现了TCP端口的扫描,并通过多线程和超时机制提高了扫描的效率。同时,用户界面设计也使得用户可以方便地进行操作和分析结果。这个课程设计编写过程不仅增强了我的Java编程能力,也提高了我的网络和安全方面的知识水平。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值