TCP端口扫描

~~重点代码
//扫描端口
private void NormalScan(Int32 state)
{
    Int32 port = state;
    String msg = "";
    TcpClient tcp = new TcpClient();
    try
    {
        tcp.Connect(IPAddress.Parse(tbxIP.Text), port);
        msg = port.ToString() + "端口开放";
        listBox.Items.Add(msg);
        tcp.Close();
    }
    catch
    {
        msg = port.ToString() + "端口不开放";
        listBox.Items.Add(msg);
    }
}
//开始扫描按钮事件
 private void btn_statrt_Click(object sender, EventArgs e)
 {
     String scanHost = tbxIP.Text;
     try
     {
         IPAddress ipaddr = (IPAddress)Dns.Resolve(scanHost).AddressList.GetValue(0);
         tbxIP.Text = ipaddr.ToString();
     }
     catch
     {
         tbxIP.Focus();
         MessageBox.Show("请输入正确的主机地址,该地址DNS无法进行解析", "系统提示");
         return;
     }

     Int32 threadNum = Convert.ToInt32(tbxStartPort.Text.Trim());
     Int32 end = Convert.ToInt32(tbxEndPort.Text.Trim());

     listBox.Items.Add("==扫描开始==");
     listBox.Refresh();

     for (; threadNum <= end; threadNum++)
     {
         NormalScan(threadNum);
         listBox.Refresh();
     }

     listBox.Items.Add("==扫描结束==");
     listBox.Refresh();
 }

~~全部代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;

namespace TCPScan
{
    public partial class FM_MAIN : Form
    {
        private string path = Application.StartupPath + "\\Logs";
        public FM_MAIN()
        {
            InitializeComponent();
        }

        private void tbxIP_KeyPress(object sender, KeyPressEventArgs e)
        {
            isNumber(e, sender);
        }

        private void tbxStartPort_KeyPress(object sender, KeyPressEventArgs e)
        {
            isNumber(e, sender);
        }

        private void tbxEndPort_KeyPress(object sender, KeyPressEventArgs e)
        {
            isNumber(e, sender);
        }
        private void btn_statrt_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(tbxIP.Text.Trim()))
            {
                MessageBox.Show("请输入IP地址", "系统提示");
                return;
            }
            if (string.IsNullOrEmpty(tbxStartPort.Text.Trim()))
            {
                MessageBox.Show("请输入起始端口号, 系统提示");
                return;
            }
            if (string.IsNullOrEmpty(tbxEndPort.Text.Trim()))
            {
                MessageBox.Show("请输入结束端口号", "系统提示");
                return;
            }

            String scanHost = tbxIP.Text;
            try
            {
                IPAddress ipaddr = (IPAddress)Dns.Resolve(scanHost).AddressList.GetValue(0);
                tbxIP.Text = ipaddr.ToString();
            }
            catch
            {
                tbxIP.Focus();
                MessageBox.Show("请输入正确的主机地址,该地址DNS无法进行解析", "系统提示");
                return;
            }

            Int32 threadNum = Convert.ToInt32(tbxStartPort.Text.Trim());
            Int32 end = Convert.ToInt32(tbxEndPort.Text.Trim());

            listBox.Items.Add("==扫描开始==");
            listBox.Refresh();

            for (; threadNum <= end; threadNum++)
            {
                NormalScan(threadNum);
                listBox.Refresh();
            }

            listBox.Items.Add("==扫描结束==");
            listBox.Refresh();
        }

        private void btn_exit_Click(object sender, EventArgs e)
        {
            System.Environment.Exit(0);
        }

        private void btn_save_Click(object sender, EventArgs e)
        {
            if (listBox.Items.Count == 0)
            {
                MessageBox.Show("没有记录,不能保存!", "系统提示");
                return;
            }
            DateTime time = DateTime.Now;
            string result = "";
            result += "================================================\r\n";
            result += "IP:" + tbxIP.Text + "\r\n";
            result += "起始端口:" + tbxStartPort.Text + "\r\n";
            result += "结束端口:" + tbxEndPort.Text + "\r\n";
            result += "保存时间:" + time.ToString("yyyy-MM-dd hh:mm:ss") + "\r\n";
            result += "================================================\r\n";
            foreach (var item in listBox.Items)
            {
                result += item + "\r\n";
            }
            if (false == System.IO.Directory.Exists(path))
            {
                System.IO.Directory.CreateDirectory(path);
            }
            string filePath = path + "\\" + tbxIP.Text.Trim() + "_" + tbxStartPort.Text.Trim() + "-" + tbxEndPort.Text.Trim() + "_" + time.ToString("yyyyMMdd hhmmss") + ".txt";
            StreamWriter sw = File.CreateText(filePath); //保存到指定路径
            sw.Write(result);
            sw.Close();
            MessageBox.Show("保存成功!\r\n路径:" + filePath, "系统提示");
        }

        private void btn_show_Click(object sender, EventArgs e)
        {
            System.Diagnostics.Process.Start(path);
        }

        private void FM_MAIN_Load(object sender, EventArgs e)
        {
            tbxIP.Text = GetLocalIP();
            tbxStartPort.Text = "75"; ;
            tbxEndPort.Text = "90";
        }

        #region Function
        public string GetLocalIP()
        {
            try
            {
                string HostName = Dns.GetHostName(); //得到主机名
                IPHostEntry IpEntry = Dns.GetHostEntry(HostName);
                for (int i = 0; i < IpEntry.AddressList.Length; i++)
                {
                    //从IP地址列表中筛选出IPv4类型的IP地址
                    //AddressFamily.InterNetwork表示此IP为IPv4,
                    //AddressFamily.InterNetworkV6表示此地址为IPv6类型
                    if (IpEntry.AddressList[i].AddressFamily == AddressFamily.InterNetwork)
                    {
                        return IpEntry.AddressList[i].ToString();
                    }
                }
                return "";
            }
            catch (Exception ex)
            {
                MessageBox.Show("获取本机IP出错:" + ex.Message, "系统提示");
                return "";
            }
        }

        private void isNumber(KeyPressEventArgs e, object sender)
        {
            /*只能数字键、退格键、负号、小数点*/
            if (((int)e.KeyChar < 48 || (int)e.KeyChar > 57) && (int)e.KeyChar != 8 &&
               (int)e.KeyChar != 45 && (int)e.KeyChar != 46) e.Handled = true;
        }

        //扫描端口
        private void NormalScan(Int32 state)
        {
            Int32 port = state;
            String msg = "";
            TcpClient tcp = new TcpClient();
            try
            {
                tcp.Connect(IPAddress.Parse(tbxIP.Text), port);
                msg = port.ToString() + "端口开放";
                listBox.Items.Add(msg);
                tcp.Close();
            }
            catch
            {
                msg = port.ToString() + "端口不开放";
                listBox.Items.Add(msg);
            }
        }
        #endregion
    }
}

运行截图

在这里插入图片描述

欢迎访问作者个人技术博客:BlackvonCode(www.blackvon.top)
作者的微信公众号和小程序
BlackvonCode

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
端口扫描软件的代码在网上很多,可是并不一定适合基础不深的鸟鸟们学。要不就是代码大多都很长而且使用了多线程(关于多线程的很多概念就够闹腾的了,扫描部分就更算了),让我等小菜都望而生畏;要不就是速度很慢,学会了也派不上用场。今天我就介绍一下自己学习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; }

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值