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

一、 编写端口扫描器程序

1.准备工作

创建新项目
在这里插入图片描述
选择Windows窗口应用
在这里插入图片描述
输入项目名称,选择代码路径,创建项目
在这里插入图片描述
控件摆放
table 4个
textbox 4个
progressBar 1个
button 1个
在这里插入图片描述
将textbox4的ReadOnly属性更改为True,用于显示结果
在这里插入图片描述

2.单线程端口扫描器

代码如下

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

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }


        //主机地址
        private string hostAddress;
        //起始端口
        private int start;
        //终止端口
        private int end;
        //端口号
        private int port;
        //定义线程对象
        private Thread scanThread;


        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                //初始化
                textBox4.Clear();
                label4.Text = "0%";
                //获取ip地址和始末端口号
                hostAddress = textBox1.Text;
                start = Int32.Parse(textBox2.Text);
                end = Int32.Parse(textBox3.Text);
                if (decideAddress())
                {
                    //让输入的textbox只读,无法改变
                    textBox1.ReadOnly = true;
                    textBox2.ReadOnly = true;
                    textBox3.ReadOnly = true;
                    //设置进度条的范围
                    progressBar1.Minimum = start;
                    progressBar1.Maximum = end;
                    //显示框显示
                    textBox4.AppendText("端口扫描器 v1.0.0" + Environment.NewLine + Environment.NewLine);
                    //调用端口扫描函数
                    PortScan();
                }
                else
                {
                    //若端口号不合理,弹窗报错
                    MessageBox.Show("输入错误,端口范围为[0-65536]!");
                }
            }
            catch
            {
                //若输入的端口号为非整型,则弹窗报错
                MessageBox.Show("输入错误,端口范围为[0-65536]!");
            }
        }

        private bool decideAddress()
        {
            //判断端口号是否合理
            if ((start >= 0 && start <= 65536) && (end >= 0 && end <= 65536) && (start <= end))
                return true;
            else
                return false;
        }

        private void PortScan()
        {
            double x;
            string xian;
            //显示扫描状态
            textBox4.AppendText("开始扫描...(可能需要请您等待几分钟)" + Environment.NewLine + Environment.NewLine);
            //循环抛出线程扫描端口
            for (int i = start; i <= end; i++)
            {
                x = (double)(i - start + 1) / (end - start + 1);
                xian = x.ToString("0%");
                port = i;
                //调用端口i的扫描操作
                Scan();
                //进度条值改变
                label4.Text = xian;
                label4.Refresh();
                progressBar1.Value = i;
            }
            textBox4.AppendText(Environment.NewLine + "扫描结束!" + Environment.NewLine);
            //输入框textbox只读属性取消
            textBox1.ReadOnly = false;
            textBox2.ReadOnly = false;
            textBox3.ReadOnly = false;
        }

        private void Scan()
        {
            int portnow = port;
            //创建TcpClient对象,TcpClient用于为TCP网络服务提供客户端连接
            TcpClient objTCP = null;
            try
            {
                //用于TcpClient对象扫描端口
                objTCP = new TcpClient(hostAddress, portnow);
                //扫描到则显示到显示框
                textBox4.AppendText("端口 " + port + " 开放!" + Environment.NewLine);
            }
            catch
            {
                //未扫描到,则会抛出错误
            }
        }
    }
}

执行,运行结果如下
在这里插入图片描述

3.多线程端口扫描器

将多线程代码稍微修改,如下
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Threading;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            //不进行跨线程检查
            CheckForIllegalCrossThreadCalls = false;
        }

        //主机地址
        private string hostAddress;
        //起始端口
        private int start;
        //终止端口
        private int end;
        //端口号
        private int port;
        //定义线程对象
        private Thread scanThread;
        //定义端口状态数据(开放则为true,否则为false)
        private bool[] done = new bool[65526];
        private bool OK;

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                //初始化
                textBox4.Clear();
                label4.Text = "0%";
                //获取ip地址和始末端口号
                hostAddress = textBox1.Text;
                start = Int32.Parse(textBox2.Text);
                end = Int32.Parse(textBox3.Text);
                if (decideAddress())
                {
                    textBox1.ReadOnly = true;
                    textBox2.ReadOnly = true;
                    textBox3.ReadOnly = true;
                    //创建线程,并创建ThreadStart委托对象
                    Thread process = new Thread(new ThreadStart(PortScan));
                    process.Start();
                    //设置进度条的范围
                    progressBar1.Minimum = start;
                    progressBar1.Maximum = end;
                    //显示框显示
                    textBox4.AppendText("端口扫描器 v1.0.0" + Environment.NewLine + Environment.NewLine);
                }
                else
                {
                    //若端口号不合理,弹窗报错
                    MessageBox.Show("输入错误,端口范围为[0-65536]!");
                }
            }
            catch
            {
                //若输入的端口号为非整型,则弹窗报错
                MessageBox.Show("输入错误,端口范围为[0-65536]!");
            }
        }

        private bool decideAddress()
        {
            //判断端口号是否合理
            if ((start >= 0 && start <= 65536) && (end >= 0 && end <= 65536) && (start <= end))
                return true;
            else
                return false;
        }

        private void PortScan()
        {
            double x;
            string xian;
            //显示扫描状态
            textBox4.AppendText("开始扫描...(可能需要请您等待几分钟)" + Environment.NewLine + Environment.NewLine);
            //循环抛出线程扫描端口
            for (int i = start; i <= end; i++)
            {
                x = (double)(i - start + 1) / (end - start + 1);
                xian = x.ToString("0%");
                port = i;
                //使用该端口的扫描线程
                scanThread = new Thread(new ThreadStart(Scan));
                scanThread.Start();
                //使线程睡眠
                System.Threading.Thread.Sleep(100);
                //进度条值改变
                label4.Text = xian;
                progressBar1.Value = i;
            }
            while (!OK)
            {
                OK = true;
                for (int i = start; i <= end; i++)
                {
                    if (!done[i])
                    {
                        OK = false;
                        break;
                    }
                }
                System.Threading.Thread.Sleep(1000);
            }
            textBox4.AppendText(Environment.NewLine + "扫描结束!" + Environment.NewLine);
            textBox1.ReadOnly = false;
            textBox2.ReadOnly = false;
            textBox3.ReadOnly = false;
        }

        private void Scan()
        {
            int portnow = port;
            //创建线程变量
            Thread Threadnow = scanThread;
            //扫描端口,成功则写入信息
            done[portnow] = true;
            //创建TcpClient对象,TcpClient用于为TCP网络服务提供客户端连接
            TcpClient objTCP = null;
            try
            {
                //用于TcpClient对象扫描端口
                objTCP = new TcpClient(hostAddress, portnow);
                //扫描到则显示到显示框
                textBox4.AppendText("端口 " + port + " 开放!" + Environment.NewLine);
            }
            catch
            {
                //未扫描到,则会抛出错误
            }
        }
    }
}

执行,结果如下
在这里插入图片描述
经过对比,多线程窗口扫描的速度比单线程快得多

二、 编写一个网游客户端

1.准备工作

1.像上面一样新建一个窗口应用项目
2.添加WindowsMediaPlayer控件
在“工具箱”中”常规“,点击“选择项”

在这里插入图片描述
选择“COM组件“,勾选上”WindowsMediaPlayer“,点击”确定“
在这里插入图片描述
3.界面设计
textbox 2个
button 3个
picturebox 1个
trackbar 1个
label 1个
groupbox 2个
WindowsMediaPlayer 1个
在这里插入图片描述
4.控件属性设置
textBox2 属性设置:需要将 Multiline 属性设为 True ,ScrollBars 属性设为 Vertical
trackBar1 属性设置:设置最大值为100,最小值为0,最小改变量为1,用于音量调节
其他属性凭自己需要

2.连接服务器

双击 “ 连接游戏 ” 按钮,转到代码编辑区,在 button2_Click 函数体内,编写连接的代码,代码如下

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

namespace GameClient
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        //分别创建 TcpClient 和 NetworkStream 的对象
        TcpClient tcpClient;
        NetworkStream stream;


        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void trackBar1_Scroll(object sender, EventArgs e)
        {

        }

        private void label1_Click(object sender, EventArgs e)
        {

        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }


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

        private void pictureBox1_Click(object sender, EventArgs e)
        {

        }

        private void axWindowsMediaPlayer1_Enter(object sender, EventArgs e)
        {

        }
    }
}

运行结果如下
在这里插入图片描述

3.传输数据

双击“发送“按钮并写入以下代码

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);
    //清除显示框之前的内容
    textBox2.Clear();
    //显示数据
    textBox2.AppendText(msg);
    //刷新输入框
    textBox1.Clear();
    //将光标集中到输入框中
    textBox1.Focus();
}

点击运行,根据提示信息就可以进行游戏了,运行效果如下
在这里插入图片描述

4.播放背景音乐

在构造函数下添加以下代码

public Form1()
        {
            InitializeComponent();

            trackBar1.Value = 50;
            label1.Text = "50";
            axWindowsMediaPlayer1.Hide();
        }

在”进入游戏“函数下添加以下代码

trackBar1.Value = 50;
label1.Text = "50";
string s = @"F:\CloudMusic\许嵩-放肆.mp3";
axWindowsMediaPlayer1.settings.setMode("loop", true);
axWindowsMediaPlayer1.settings.volume = 50;
axWindowsMediaPlayer1.URL = s;

双击 TrackBar1 控件后,在函数下写入以下代码

private void trackBar1_Scroll_1(object sender, EventArgs e)
        {
            //控制音量大小
            axWindowsMediaPlayer1.settings.volume = trackBar1.Value;
            //控制音量显示
            label1.Text = trackBar1.Value.ToString();
        }

运行程序,点击进入游戏会马上播放准备好的音乐,并且通过拉条可以改变音乐大小
在这里插入图片描述

5.变换背景图片

进入设计界面,添加一个 timer 控件
在这里插入图片描述
修改 timer1 属性,因为是以毫秒为单位,所以设定 30000
在这里插入图片描述
双击”timer1“控件,添加以下代码

private int flag = 0;
        private void timer1_Tick(object sender, EventArgs e)
        {
            flag++;
            string picturePath = @"D:\picture\" + flag + ".jpg";
            //设置图片填充
            pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
            pictureBox1.Image = Image.FromFile(picturePath);
            if (flag == 5)
            {
                flag = 0;
            }
        }

运行,结果如下
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值