端口扫描及简易游戏客户端

本文介绍了如何编写端口扫描器程序,分别从单线程和多线程的角度进行了实现,并对比了两者的性能差异。此外,还详细讲解了如何从头开始构建一个网络游戏客户端,包括新建工程、设计界面、编写代码到最后的结果展示。
摘要由CSDN通过智能技术生成

一、编写端口扫描器程序

1.采用单线程

(1)新建项目
在这里插入图片描述

(2)设计界面
在这里插入图片描述
(3)代码编写

using System;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
namespace WindowsFormApp1
{
    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  PortScan()
        {
            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
            {

            }

        }
    }
}


(4)运行结果
在这里插入图片描述

2.采用多线程

(1)创建项目过程如上
(2)代码编写

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Threading;
namespace PortScanner
{
    public class Form1 : System.Windows.Forms.Form
    {
        private System.Windows.Forms.TextBox txtAddr;
        private System.Windows.Forms.TextBox txtStart;
        private System.Windows.Forms.TextBox txtEnd;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.Label label2;
        private System.Windows.Forms.Label label3;
        private System.Windows.Forms.Splitter splitter1;
        private System.Windows.Forms.ListBox lbResult;
        private System.Windows.Forms.Button btnScan;
        private System.Windows.Forms.ProgressBar progressBar1;
        private System.Windows.Forms.Label lblStart;
        private System.Windows.Forms.Label lblStop;
        private System.Windows.Forms.Label lblNow;
        //自定义变量
        private int port;
        private string Addr;
        private bool[] done = new bool[65536];
        private int start;
        private int end;
        private Thread scanThread;
        private bool OK;
        public Form1()
        {
            InitializeComponent();
        }
        private void InitializeComponent()
        {
            this.lbResult = new System.Windows.Forms.ListBox();
            this.txtAddr = new System.Windows.Forms.TextBox();
            this.txtStart = new System.Windows.Forms.TextBox();
            this.txtEnd = new System.Windows.Forms.TextBox();
            this.label1 = new System.Windows.Forms.Label();
            this.label2 = new System.Windows.Forms.Label();
            this.label3 = new System.Windows.Forms.Label();
            this.splitter1 = new System.Windows.Forms.Splitter();
            this.btnScan = new System.Windows.Forms.Button();
            this.progressBar1 = new System.Windows.Forms.ProgressBar();
            this.lblStart = new System.Windows.Forms.Label();
            this.lblStop = new System.Windows.Forms.Label();
            this.lblNow = new System.Windows.Forms.Label();
            this.SuspendLayout();
            // 
            // lbResult
            // 
            this.lbResult.Dock = System.Windows.Forms.DockStyle.Right;
            this.lbResult.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.lbResult.ItemHeight = 14;
            this.lbResult.Location = new System.Drawing.Point(224, 0);
            this.lbResult.Name = "lbResult";
            this.lbResult.Size = new System.Drawing.Size(264, 273);
            this.lbResult.TabIndex = 0;
            this.lbResult.SelectedIndexChanged += new System.EventHandler(this.lbResult_SelectedIndexChanged);
            // 
            // txtAddr
            // 
            this.txtAddr.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.txtAddr.Location = new System.Drawing.Point(72, 16);
            this.txtAddr.Name = "txtAddr";
            this.txtAddr.Size = new System.Drawing.Size(136, 22);
            this.txtAddr.TabIndex = 1;
            // 
            // txtStart
            // 
            this.txtStart.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.txtStart.Location = new System.Drawing.Point(72, 48);
            this.txtStart.Name = "txtStart";
            this.txtStart.Size = new System.Drawing.Size(136, 22);
            this.txtStart.TabIndex = 2;
            this.txtStart.TextChanged += new System.EventHandler(this.txtStart_TextChanged);
            // 
            // txtEnd
            // 
            this.txtEnd.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.txtEnd.Location = new System.Drawing.Point(72, 80);
            this.txtEnd.Name = "txtEnd";
            this.txtEnd.Size = new System.Drawing.Size(136, 22);
            this.txtEnd.TabIndex = 3;
            this.txtEnd.TextChanged += new System.EventHandler(this.txtEnd_TextChanged);
            // 
            // label1
            // 
            this.label1.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.label1.Location = new System.Drawing.Point(8, 16);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(64, 23);
            this.label1.TabIndex = 4;
            this.label1.Text = "主机地址";
            // 
            // label2
            // 
            this.label2.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.label2.Location = new System.Drawing.Point(8, 80);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(64, 23);
            this.label2.TabIndex = 5;
            this.label2.Text = "结束端口";
            // 
            // label3
            // 
            this.label3.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.label3.Location = new System.Drawing.Point(8, 48);
            this.label3.Name = "label3";
            this.label3.Size = new System.Drawing.Size(64, 23);
            this.label3.TabIndex = 6;
            this.label3.Text = "起始端口";
            // 
            // splitter1
            // 
            this.splitter1.Dock = System.Windows.Forms.DockStyle.Right;
            this.splitter1.Location = new System.Drawing.Point(221, 0);
            this.splitter1.Name = "splitter1";
            this.splitter1.RightToLeft = System.Windows.Forms.RightToLeft.Yes;
            this.splitter1.Size = new System.Drawing.Size(3, 273);
            this.splitter1.TabIndex = 7;
            this.splitter1.TabStop = false;
            // 
            // btnScan
            // 
            this.btnScan.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.btnScan.Location = new System.Drawing.Point(72, 200);
            this.btnScan.Name = "btnScan";
            this.btnScan.Size = new System.Drawing.Size(75, 23);
            this.btnScan.TabIndex = 8;
            this.btnScan.Text = "扫描";
            this.btnScan.Click += new System.EventHandler(this.btnScan_Click);
            // 
            // progressBar1
            // 
            this.progressBar1.Location = new System.Drawing.Point(8, 112);
            this.progressBar1.Name = "progressBar1";
            this.progressBar1.Size = new System.Drawing.Size(200, 23);
            this.progressBar1.Step = 1;
            this.progressBar1.TabIndex = 9;
            // 
            // lblStart
            // 
            this.lblStart.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.lblStart.Location = new System.Drawing.Point(8, 144);
            this.lblStart.Name = "lblStart";
            this.lblStart.Size = new System.Drawing.Size(48, 23);
            this.lblStart.TabIndex = 10;
            // 
            // lblStop
            // 
            this.lblStop.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.lblStop.Location = new System.Drawing.Point(160, 144);
            this.lblStop.Name = "lblStop";
            this.lblStop.Size = new System.Drawing.Size(48, 23);
            this.lblStop.TabIndex = 11;
            // 
            // lblNow
            // 
            this.lblNow.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.lblNow.Location = new System.Drawing.Point(84, 144);
            this.lblNow.Name = "lblNow";
            this.lblNow.Size = new System.Drawing.Size(48, 23);
            this.lblNow.TabIndex = 12;
            // 
            // Form1
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(6, 15);
            this.ClientSize = new System.Drawing.Size(488, 273);
            this.Controls.Add(this.lblNow);
            this.Controls.Add(this.lblStop);
            this.Controls.Add(this.lblStart);
            this.Controls.Add(this.progressBar1);
            this.Controls.Add(this.btnScan);
            this.Controls.Add(this.splitter1);
            this.Controls.Add(this.label3);
            this.Controls.Add(this.label2);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.txtEnd);
            this.Controls.Add(this.txtStart);
            this.Controls.Add(this.txtAddr);
            this.Controls.Add(this.lbResult);
            this.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.Name = "Form1";
            this.Text = "端口扫描器";
            this.ResumeLayout(false);
            this.PerformLayout();

        }
        [STAThread]
        static void Main()
        {
           // Control.CheckForIllegalCrossThreadCalls = false;
            Application.Run(new Form1());
        }

        private void txtStart_TextChanged(object sender, System.EventArgs e)
        {
            //获取输入的起始端口值
            lblStart.Text = txtStart.Text;
        }
        private void txtEnd_TextChanged(object sender, System.EventArgs e)
        {
            //获取输入的接受端口值
            lblStop.Text = txtEnd.Text;
        }
        private void btnScan_Click(object sender, System.EventArgs e)
        {
            //创建线程,并创建ThreadStart委托对象
            Thread process = new Thread(new ThreadStart(PortScan));
            process.Start();
            //显示端口扫描的范围
            progressBar1.Minimum = Int32.Parse(txtStart.Text);
            progressBar1.Maximum = Int32.Parse(txtEnd.Text);
            //显示框初始化
            lbResult.Items.Clear();
            lbResult.Items.Add("端口扫描器 v1.0.");
            lbResult.Items.Add("");
        }
        private void PortScan()
        {
            start = Int32.Parse(txtStart.Text);
            end = Int32.Parse(txtEnd.Text);
            //检查输入范围合法性
            if ((start >= 0 && start <= 65536) && (end >= 0 && end <= 65536) && (start <= end))
            {
                lbResult.Items.Add("开始扫描... (可能需要请您等待几分钟)");
                Addr = txtAddr.Text;
                for (int i = start; i <= end; i++)
                {
                    port = i;
                    //使用该端口的扫描线程
                    scanThread = new Thread(new ThreadStart(Scan));
                    scanThread.Start();
                    //使线程睡眠
                    System.Threading.Thread.Sleep(100);
                    progressBar1.Value = i;
                    lblNow.Text = i.ToString();
                }
                //未完成时情况
                while (!OK)
                {
                    OK = true;
                    for (int i = start; i <= end; i++)
                    {
                        if (!done[i])
                        {
                            OK = false;
                            break;
                        }
                    }
                    System.Threading.Thread.Sleep(1000);
                }
                lbResult.Items.Add("扫描结束!");
            }
            else
            {
                MessageBox.Show("输入错误,端口范围为[0-65536]");
            }
        }
        private void Scan()
        {
            int portnow = port;
            //创建线程变量
            Thread Threadnow = scanThread;
            done[portnow] = true;
            //创建TcpClient对象,TcpClient用于为TCP网络服务提供客户端连接
            TcpClient objTCP = null;
            //扫描端口,成功则写入信息
            try
            {
                //用TcpClient对象扫描端口
                objTCP = new TcpClient(Addr, portnow);
                lbResult.Items.Add("端口 " + portnow.ToString() + " 开放!");
            }
            catch
            {
            }
        }


    }
}

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

3.单线程与多线程比较

单线程的也就是程序执行时,所跑的程序路径(处理的东西)是连续顺序下来的,必须前面的处理好,后面的才会执行到。单线程程序:只有一个线程,代码顺序执行,容易出现代码阻塞。

多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务,线程间独立运行,能有效地避免代码阻塞,并且提高程序的运行性能。
参考多线程好还是单线程好?单线程和多线程的区别 优缺点分析

二、编写一个网游客户端

1.新建工程

在这里插入图片描述

2.设计界面

在这里插入图片描述

3.编写代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace  Jymclient
{
    public partial class Form1 : Form
    {
        private int flag = 0;
        TcpClient tcpClient;
        NetworkStream stream;

        public Form1()
        {
            InitializeComponent();

        
        }

        /*****************
         * 进入游戏
         *****************/
        private void button2_Click(object sender, EventArgs e)
        {
            /*
                * 连接服务器
                */
            try
            {
                //实例化
                tcpClient = new TcpClient();
                //向指定的IP地址的服务器发出连接请求
                tcpClient.Connect("10.160.52.106", 3900);
                //获取网络传输流
                stream = tcpClient.GetStream();
                //接受数据并转化为字符串
                byte[] data = new byte[1024];
                int receive = stream.Read(data, 0, 1024);
                string msg = Encoding.Default.GetString(data, 0, receive);
                //去除字符串中的终端转义字符
                msg = strDelete(msg);
                //显示出来
                textBox2.AppendText(msg);
            }
            catch
            {
                textBox2.AppendText("服务器未启动" + Environment.NewLine);
            }

            /******************
             * 播放背景音乐
             ******************/
          
            //字符串存储音乐路径
            string s = @"D:\windowsz\wu.mp3";
            //设置为循环播放
            axWindowsMediaPlayer1.settings.setMode("loop", true);
            //设置初始音乐的音量大小(范围:0——100)
            axWindowsMediaPlayer1.settings.volume = 50;
            //设置播放歌曲的路径
            axWindowsMediaPlayer1.URL = s;
        }

        /*****************
         * 去除终端转移字符
         *****************/
        private string strDelete(string str)
        {
            int flag = -1, de = 0;
            for (int i = 0; i < str.Length; i++)
            {
                if (str[i] == '')
                {
                    flag = i;
                }
                if (flag != -1)
                {
                    de++;
                }
                if (str[i] == 'm' && flag != -1)
                {
                    str = str.Remove(flag, de);
                    i = flag - 1;
                    flag = -1;
                    de = 0;
                }
            }
            return str;
        }

        /*****************
         * 发送数据
         *****************/
        private void button1_Click(object sender, EventArgs e)
        {
            //获取textBox1内的文本内容
            string msg = textBox1.Text + "\n";
            //将文本内容转化成比特流并发送给服务器
            byte[] data = new byte[1024];
            data = Encoding.Default.GetBytes(msg);
            stream.Write(data, 0, data.Length);
            //接收服务器端传来的数据流并转化为字符串
            byte[] data1 = new byte[1024];
            int receive = stream.Read(data1, 0, 1024);
            msg = Encoding.Default.GetString(data1, 0, receive);
            //去除字符串中的终端转义字符
            msg = strDelete(msg);
            //清除显示框之前的内容
            textBox2.Clear();
            //显示数据
            textBox2.AppendText(msg);
            //刷新输入框
            textBox1.Clear();
            textBox1.Focus();
        }

        /*****************
         * 自动换图
         *****************/
        private void timer1_Tick(object sender, EventArgs e)
        {
            flag++;
            string picturePath = @"C:\Users\ASUS\Pictures\" + flag + ".jpg";
            //设置图片填充
            pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
            pictureBox1.Image = Image.FromFile(picturePath);
            if (flag == 5)
            {
                flag = 0;
            }
        }

        /*****************
         * 退出游戏
         *****************/
        private void button3_Click(object sender, EventArgs e)
        {
            if(stream != null)
            {
                stream.Close();
                tcpClient.Close();
            }
            textBox2.Clear();
            //停止播放背景音乐
            axWindowsMediaPlayer1.Ctlcontrols.stop();
        }
    }
}

4.结果显示

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值