一、 编写端口扫描器程序
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;
}
}
运行,结果如下