TCP编程-端口扫描器与网游客户端

本文介绍了如何编写端口扫描程序,包括单一进程和多线程实现方式,并进行了对比分析。接着讲解了网游客户端的实现,包括连接服务器及向服务器发送数据的步骤,展示了程序运行效果。
摘要由CSDN通过智能技术生成

编写端口扫描程序

一、准备工作

1、创建工程
在这里插入图片描述

2、选择项目类型为Windows窗体应用
在这里插入图片描述

3、填写信息
在这里插入图片描述
4、设置界面
在这里插入图片描述

二、采用单一进程实现端口扫描

代码:

using System;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
namespace homework33
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        //自定义变量
        private int port;//记录当前扫描的端口号
        private string Address;//记录扫描的系统地址
        private bool[] done = new bool[65536];//记录端口的开放状态
        private int start;//记录扫描的起始端口
        private int end;//记录扫描的结束端口
        private bool OK;

        private void button1_Click(object sender, EventArgs e)
        {
            label4.Text = textBox2.Text;
            label6.Text = textBox3.Text;
            progressBar1.Minimum = Int32.Parse(textBox2.Text);
            progressBar1.Maximum = Int32.Parse(textBox3.Text);
            listBox1.Items.Clear();
            listBox1.Items.Add("端口扫描器v1.0.");
            listBox1.Items.Add("");
            PortScan();

        }
        private void  homework33()
        {
            start = Int32.Parse(textBox2.Text);
            end = Int32.Parse(textBox3.Text);
            //判断输入端口是否合法
            if((start>=0&&start<=65536)&&(end>=0&&end<=65536)&&(start<=end))
            {
                listBox1.Items.Add("开始扫描:这个过程可能需要等待几分钟!");
                Address = textBox1.Text;
                for(int i = start; i <= end; i++)
                {
                    port = i;
                    Scan();
                    progressBar1.Value = i;
                    label5.Text = i.ToString();
                }
                while (!OK)
                {
                    OK = true;
                    for(int i = start; i <= end; i++)
                    {
                        if (!done[i])
                        {
                            OK = false;
                            break;
                        }
                    }
                }
                listBox1.Items.Add("扫描结束!");
            }
            else
            {
                MessageBox.Show("输入错误,端口范围为[0,65536]");
            }
        }
        //连接端口
        private void Scan()
        {
            int portnow = port;
            done[portnow] = true;
            TcpClient objTCP = null;
            try
            {
                objTCP = new TcpClient(Address, portnow);
                listBox1.Items.Add("端口"+portnow.ToString()+"开放");
            }
            catch
            {

            }

        }
    }
}

3、运行结果
在这里插入图片描述

三、多线程实现端口扫描

代码:

using System;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace homework33
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        //自定义变量
        private int port;//记录当前扫描的端口号
        private string Address;//记录扫描的系统地址
        private bool[] done = new bool[65536];//记录端口的开放状态
        private int start;//记录扫描的起始端口
        private int end;//记录扫描的结束端口
        private bool OK;
        private Thread scanThread;  
        //将输入的起始端口放到进度条的开始位置
        private void label4_TextChanged(object sender, EventArgs e)
        {
            label4.Text = textBox2.Text;
        }
        //将输入的结束地址放到进度条的结束位置
        private void label6_TextChanged(object sender, EventArgs e)
        {
            label6.Text = textBox3.Text;
        }
        private void button1_Click(object sender, EventArgs e)
        {
            label4_TextChanged(sender, e);
            label6_TextChanged(sender, e);
            //创建线程,并创建ThreadStart委托对象
            Thread procss = new Thread(new ThreadStart(homework33));
            procss.Start();
            //显示端口扫描范围
            progressBar1.Minimum = Int32.Parse(textBox2.Text);
            progressBar1.Maximum = Int32.Parse(textBox3.Text);
            //显示框的初始化
            listBox1.Items.Clear();
            listBox1.Items.Add("端口扫描器v1.0.");
            listBox1.Items.Add("");

        }
        private void homework33()
        {
            start = Int32.Parse(textBox2.Text);
            end = Int32.Parse(textBox3.Text);
            //检查端口的合法性
            if ((start >= 0 && start <= 65536) && (end >= 0 && end <= 65536) && (start <= end))
            {
                listBox1.Items.Add("开始扫描:这个过程可能需要等待几分钟!");
                Address = textBox1.Text;
                for (int i = start; i <= end; i++)
                {
                    port = i;
                    //对该端口进行扫描的线程
                    scanThread = new Thread(Scan);
                    scanThread.Start();
                    //使线程睡眠
                    System.Threading.Thread.Sleep(100);
                    progressBar1.Value = i;
                    label5.Text = i.ToString();
                }
                //未完成时情况
                while (!OK)
                {
                    OK = true;
                    for (int i = start; i <= end; i++)
                    {
                        if (!done[i])
                        {
                            OK = false;
                            break;
                        }
                    }
                }
                listBox1.Items.Add("扫描结束!");
                System.Threading.Thread.Sleep(1000);
            }
            else
            {
                MessageBox.Show("输入错误,端口范围为[0,65536]");
            }
        }
        private void Scan()
        {
            int portnow = port;
            //创建线程变量
            Thread Threadnow = scanThread;
            done[portnow] = true;
            //创建TcpClient对象,TcpClient用于TCP网络服务提供客户端连接
            TcpClient objTCP = null;
            //扫描端口,成功就写入信息
            try
            {
                objTCP = new TcpClient(Address, portnow);
                listBox1.Items.Add("端口" + portnow.ToString() + "开放!");
            }
            catch
            {

            }
        }
    }
}


结果演示:
在这里插入图片描述

两者对比

线程:程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针、程序计数器等),但代码区是共享的,即不同的线程可以执行同样的函数。
进程:当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源。而一个进程又是由多个线程所组成的。
多线程:指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务。

在一些情况下,采用多线程会使程序更加优化,实现功能效率更高。总的来说,采用多线程的方式具有较大的优势。该程序用来查看系统开启哪些端口服务。

编写网游客户端

一连接服务器

代码:

private NetworkStream stream;
private TcpClient tcpClient = new TcpClient();
public Form1()
{
      InitializeComponent();
      try
            {
                //向指定的IP地址的服务器发出连接请求
                tcpClient.Connect("10.160.52.106", 3900);
                listBox1.Items.Add("连接成功!");
                stream = tcpClient.GetStream();
                byte[] data = new byte[1024];
                //判断网络流是否可读            
                if (stream.CanRead)
                {
                    int len = stream.Read(data, 0, data.Length);
                    //Encoding ToEncoding = Encoding.GetEncoding("UTF-8");
                    //Encoding FromEncoding = Encoding.GetEncoding("GB2312");
                    //data=Encoding.Convert(FromEncoding, ToEncoding, data);
                    //string msg = Encoding.UTF8.GetString(data, 0, data.Length);
                    string msg = Encoding.Default.GetString(data, 0, data.Length);
                    string str = "\r\n";
                    char[] str1 = str.ToCharArray();
                    string[] msg1=msg.Split(str1);
                    for(int j = 0; j < msg1.Length; j++)
                    {
                        listBox1.Items.Add(msg1[j]);
                    }
                }
            }
            catch
            {
                listBox1.Items.Add("服务器未启动!");
            }
}

先为界面创建一个TCPClient对象属性,在窗体初始化的时候,就连接服务器,并把服务器返回的数据在ListBox中显示出来。

二、客户端向服务器发送数据

private void button12_Click(object sender, EventArgs e)
{
     //判断连接是否断开
     if (tcpClient.Connected)
     {
     	//向服务器发送数据
      	string msg = textBox1.Text;
        Byte[] outbytes = System.Text.Encoding.Default.GetBytes(msg+"\n");
        stream.Write(outbytes, 0, outbytes.Length);
        byte[] data = new byte[1024];
        //接收服务器回复数据
        if (stream.CanRead)
         {
         	int len = stream.Read(data, 0, data.Length);
            string msg1 = Encoding.Default.GetString(data, 0, data.Length);
            string str = "\r\n";
            char[] str1 = str.ToCharArray();
            string[] msg2 = msg1.Split(str1);
            for (int j = 0; j < msg2.Length; j++)
            {
            	listBox1.Items.Add(msg2[j]);
            }
         }
      }
      else
      {
       	listBox1.Items.Add("连接已断开");
      }
}

将输入到textBox中的信息发送给服务器,再将服务器发送回来的数据给添加到ListBox中显示出来。
运行效果:

S扫描是一个简单的使用两种常用的扫描方式进行端口扫描端口扫描程序. 可实现的功能是: 1.两种不同的扫描方式(SYN扫描和一般的connect扫描) 2.可以扫描单个IP或IP段所有端口 3.可以扫描单个IP或IP段单个端口 4.可以扫描单个IP或IP段用户定义的端口 5.可以显示打开端口的banner 6.可将结果写入文件 7.TCP扫描可自定义线程数 用法:scanner TCP/SYN StartIP [EndIP] Ports [Threads] [/Banner] [/Save] 参数说明: TCP/SYN -> TCP方式扫描或SYN方式扫描(SYN扫描需要在win 2k或以上系统才行),SYN扫描对本机无效 StartIP -> 起始扫描的IP EndIP -> 结束扫描的IP,可选项,如果这一项没有,就只是对单个IP扫描 Ports -> 可以是单个端口,连续的一段端口或非连续的端口 Threads -> 使用最大线程数去扫描(SYN扫描不需要加这一项),不能超过1024线程 /Banner -> 扫描端口时一并将Banner显示出来,这一选项只对TCP扫描有效 /Save -> 将结果写入当前目录的Result.txt文件中去 我们先点击开始菜单--->运行--->CMD.EXE,因为我把扫描放在F盘,你们的扫描放哪你们就进哪里, 打开S扫描,下面我举几个例子演示下S扫描的主要几个作用。 例子一: S TCP 218.80.12.1 218.80.12.123 80 512 TCP扫描218.80.12.1到218.80.12.123这IP段中的80端口,最大并发线程是512 例子二: S TCP 218.80.12.1 218.80.12.123 21,5631 512 /Banner TCP扫描218.80.12.1到218.80.12.123这IP段中的21和5631端口,最大并发线程是512,并显示Banner 例子三: S TCP 218.80.12.1 218.80.12.12 1-200 512 TCP扫描218.80.12.1到218.80.12.12这IP段中的1到200端口,最大并发线程是512 例子四: S TCP 218.80.12.7 1-200 512 TCP扫描218.80.12.7这IP中的1到200端口,最大并发线程是512 例子五: S SYN 218.80.12.7 1-65535 /Save SYN扫描218.80.12.7这IP中的1到65535端口,将结果写入Result.txt 扫描结束后Result.txt就存放在你的S扫描所在的硬盘里,就是这个文档。刚才扫描的东西都在里面。 例子六: S SYN 218.80.12.1 218.80.12.255 21 /Save TCP扫描218.80.12.1到218.80.12.255这IP段中的21端口,将结果写入Result.txt 这个我重点说明一下,因为这条命令就是专门用来找肉鸡的,扫描一个IP段有没有开3389的或1433的 我示范下:S SYN 218.80.1.1 218.80.255.255 3389 /Save (找开放3389肉鸡的指令,矮鸟要牢记哦) 我晕哦,好多开了3389的,大家只要利用这指令扫到开3389的IP,再用别工具继续扫开了3389的肉鸡的弱口令 找到了马上建立管理员,登陆进去,你就算得到一个肉鸡了,由于本动画不是教找肉鸡的,我也不进行操作了 注意: 1.SYN扫描是很依赖于扫描者和被扫描者的网速的,如果你是内网的系统,那你不一定可以使用SYN扫描的 ,因为你的网关的类型会决定内网系统是否能进行SYN扫描.如果你的配置较低的话,我也不推荐使用 SYN扫描.SYN扫描速度是比TCP扫描的速度快很多的,但在稳定性方面却不是太好,所以自己决定使用 哪种模式进行扫描。 2.SYN扫描不需要线程那个参数,请看上面例子5和6 3.TCP扫描的最大并发线程不能超过1024. 4.使用SYN模式扫描,不能扫描Banner,具体为什么不能,请查看有关SYN的资料。 对于有些朋友说XP-SP2不能用S扫描,有的说可以使用,本人就不大清楚了,懂得人请说明下XP-SP2能不能使用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值