TCP编程与网游客户端

TCP编程与网游客户端

实验环境:Visual Studio 2017 社区版

一.编写端口扫描器程序

单线程

1.新建项目
文件–>新项目–C#窗口应用。
在这里插入图片描述
2.设计界面
在这里插入图片描述
3.主要代码

using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace PortScanner2
{
    public partial class Form1 : Form
    {
        //自定义变量
        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 textBox2_TextChanged(object sender, EventArgs e)
        {
            label4.Text = textBox2.Text;

        }

        private void textBox3_TextChanged(object sender, EventArgs e)
        {
            label6.Text = textBox3.Text;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //显示端口扫描的范围
            progressBar1.Minimum = Int32.Parse(textBox2.Text);
            progressBar1.Maximum = Int32.Parse(textBox3.Text);
            //显示框初始化
            listBox1.Items.Clear();
            listBox1.Items.Add("端口扫描器 v1.0.");
            listBox1.Items.Add("");
            //调用函数PortScan
            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("开始扫描... (可能需要请您等待几分钟)");
                Addr = textBox1.Text;
                for (int i = start; i <= end; i++)
                {
                    port = i;
                    //使用该端口的扫描线程
                    //scanThread = new Thread(new ThreadStart(Scan));
                    // scanThread.Start();
                    //使线程睡眠
                    // System.Threading.Thread.Sleep(100);
                    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;
                        }
                    }
                    System.Threading.Thread.Sleep(1000);
                }
                listBox1.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);
                listBox1.Items.Add("端口 " + portnow.ToString() + " 开放!");
            }
            catch
            {
            }
        }
    }
}

4.执行结果
在这里插入图片描述

多线程

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;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace PortScanner1
{
    public partial class Form1 : Form
    {
        //自定义变量
        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();
            CheckForIllegalCrossThreadCalls = false;//这行代码若不加,执行的时候会报错
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //创建线程,并创建ThreadStart委托对象
            Thread process = new Thread(new ThreadStart(PortScan));
            process.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 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("开始扫描... (可能需要请您等待几分钟)");
                Addr = textBox1.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;
                    label6.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);
                }
                listBox1.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);
                listBox1.Items.Add("端口 " + portnow.ToString() + " 开放!");
            }
            catch
            {
            }
        }

        private void textBox3_TextChanged(object sender, EventArgs e)
        {
            label5.Text = textBox3.Text;
        }

        private void textBox2_TextChanged(object sender, EventArgs e)
        {
            label4.Text = textBox2.Text;
        }
    }  
}

4.执行结果
在这里插入图片描述
从二者执行的结果可以看出,使用多线程执行要比单线程执行快的多。

二.编写一个网游客户端,游戏服务器的校园内网IP地址为 10.160.52.106,端口为3900,采用TCP连接

1.新建一个C#窗口项目命名为gametest,步骤与前面一样,这里就不再上图了
2设计游戏客户端界面
(1)添加播放音乐的组件:工具–>选择工具箱–>COM组件
在这里插入图片描述
(2)添加窗口控件,鼠标左键点中拖动即可,如果找不到控件在哪里,也可以搜索
在这里插入图片描述
(3)将label,button,TextBox,ListBox,label,windowsmediaplayer,pictureBox等控件拖入图形设计界面,其效果如下
在这里插入图片描述
(4)改变控件的属性,比如label,button的Text,font等属性
在这里插入图片描述
(5)添加图片到imagelist里面:右键imagelist–>选择图像–>如下窗口–>添加–>选择图片即可(图片的size最好一样)
在这里插入图片描述
(6)设置pictureBox的属性,这里关系到背景图片切换时的清晰度,ImageSize应与imagelist的第一张相同,colorDepth选择最大值。
在这里插入图片描述
(7)另外,可以更改axWindowsMediaPlayer的属性,使之执行时不可见,将Visable的值由原来的true改为false。
在这里插入图片描述
(8)更改定时器Timer的属性,使背景图片(picturebox)每30秒切换一次。
在这里插入图片描述

3相关代码
(1)连接服务器代码

        private NetworkStream stream;
        private TcpClient tcpClient = new TcpClient();//创建一个TCP的客户端

        public Form1()
        {
            InitializeComponent();
            try
            {
                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("服务器未启动!");
            }
        }

(2)发送消息的代码

 private void button1_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("连接已断开");
                }
            }
        }

(4)播放背景音乐的代码

//背景音乐的播放
        private void button12_Click(object sender, EventArgs e)
        {
            try
            {
               // String m = @"baizhanchengshi.mp3";
                String m=@"E:\MicrosoftVisualStudio\Gametest\Gametest\baizhanchengshi.mp3";
                axWindowsMediaPlayer1.URL = m;
            }
            catch
            {
                listBox1.Items.Add("背景音乐播放失败");
            }
        }
        private void button13_Click(object sender, EventArgs e)
        {
            axWindowsMediaPlayer1.Ctlcontrols.pause();
        }

(5)背景图片的自动切换

 /*
         背景图片的自动切换
        */
        private int im = 0;

        private void timer1_Tick(object sender, EventArgs e)
        {
            //this.BackgroundImage = imageList1.Images[im++ % 5];
            //pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
           pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
           pictureBox1.Image = imageList1.Images[im++ % 5];
            //pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;

            //groupBox1.BackgroundImageLayout = ImageLayout.Stretch;
            //this.BackgroundImageLayout = ImageLayout.Zoom;
        }

4.form.cs全部代码

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 Gametest
{
    public partial class Form1 : Form
    {
        private NetworkStream stream;
        private TcpClient tcpClient = new TcpClient();

        public Form1()
        {
            InitializeComponent();
            try
            {
                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("服务器未启动!");
            }
        }

        private void button1_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("连接已断开");
                }
            }
        }
        //背景音乐的播放
        private void button12_Click(object sender, EventArgs e)
        {
            try
            {
               // String m = @"baizhanchengshi.mp3";
                String m=@"E:\MicrosoftVisualStudio\Gametest\Gametest\baizhanchengshi.mp3";
                axWindowsMediaPlayer1.URL = m;
            }
            catch
            {
                listBox1.Items.Add("背景音乐播放失败");
            }
        }
        private void button13_Click(object sender, EventArgs e)
        {
            axWindowsMediaPlayer1.Ctlcontrols.pause();
        }
        /*
         背景图片的自动切换
        */
        private int im = 0;

        private void timer1_Tick(object sender, EventArgs e)
        {
            //this.BackgroundImage = imageList1.Images[im++ % 5];
            //pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
           pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
           pictureBox1.Image = imageList1.Images[im++ % 5];
            //pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;

            //groupBox1.BackgroundImageLayout = ImageLayout.Stretch;
            //this.BackgroundImageLayout = ImageLayout.Zoom;
        }

        //关闭连接
        private void button2_Click(object sender, EventArgs e)
        {
            tcpClient.Close();
            listBox1.Items.Add("已断开连接");
        }

        
    }
}

5.执行结果

在这里插入图片描述

总结

这次练习加深了我对C#From的了解,对各种控件更加的熟悉了,如果有什么不对的地方,望指出,感谢

参考文档
背景图片的切换
图片模糊的解决方法
网游客户端设计

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值