📄 update.cs
字号:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using IMLibrary;
using System.IO;
namespace LanMsg
{
public partial class AppUpdate : UserControl
{
public AppUpdate()
{
InitializeComponent();
}
#region 变量区域
/// <summary>
/// 升级文件的大小
/// </summary>
public int fileLen=0;
/// <summary>
/// 升级服务器的IP地址
/// </summary>
public System.Net.IPAddress serverIp = System.Net.IPAddress.Parse("10.211.1.39");
/// <summary>
/// 升级服务器的端口号
/// </summary>
public int serverPort = 5678;
/// <summary>
/// 更新文件内存数组
/// </summary>
public byte[] FileBlock;
/// <summary>
/// 最后一次获得文件数据包的位置
/// </summary>
private int LastPos = 0;
/// <summary>
/// 当前获得文件的位置
/// </summary>
private int currGetPos = 0;//
#endregion
#region 数据达到事件处理过程DataArrival(byte[] Data, System.Net.IPAddress Ip, int Port)
private void sockUDP1_DataArrival(byte[] Data, System.Net.IPAddress Ip, int Port)
{
DataArrivaldelegate outdelegate = new DataArrivaldelegate(DataArrival);
this.BeginInvoke(outdelegate, new object[] { Data, Ip, Port });
}
private delegate void DataArrivaldelegate(byte[] Data, System.Net.IPAddress Ip, int Port);
private void DataArrival(byte[] Data, System.Net.IPAddress Ip, int Port)
{
int cnt = 0;//记录接收到的数据包大小
cnt = Data.Length;//获取接收到的数据包大小
if (cnt < 3) return;//如果收到的数据小于3个字节则视为非法用户,抛弃
if (Data[0] != 255) return;//将非法用户的数据抛弃
try
{
byte[] buffer = new byte[cnt - 2];//申明一个字节数组,用于保存去除第一个字节码(即LanMsg协议编码)的其它数据(即消息实体)
Buffer.BlockCopy(Data, 2, buffer, 0, cnt - 2);//去除前两个字节码(即LanMsg协议编码)的其它数据为消息实体,将其保存于Buffer字节数组
switch (Data[1])// 取得第一个字节码,即LanMsg协议编码,根据编码判断用户发过来的请求为何种类型
{
case 1:// 收到服务器发送过来的文件块
this.ReceivedFileBlock(new IMLibrary.DataArrivalEventArgs(buffer, Ip, Port));
break;
case 2://服务器通知有新版本,并返回升级包文件大小
this.getFileLen(new IMLibrary.DataArrivalEventArgs(buffer, Ip, Port));
break;
}
}
catch
{ }
}
#endregion
#region 获得服务器提供的升级包大小
/// <summary>
/// 获得服务器提供的升级包大小
/// </summary>
/// <param name="e"></param>
private void getFileLen(DataArrivalEventArgs e)
{
int len = IMLibrary.TextEncoder.bytesToInt(e.Data);
this.fileLen = len;
if (MessageBox.Show("LanMsg 已经有更新版本,是否下载并安装更新?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes)
{
try
{
this.xpProgressBar1.PositionMax = this.fileLen;
this.label1.Text = "正在下载更新...";
this.FileBlock = new byte[this.fileLen];
this.sendRequestGetFileData();
}
catch (Exception x)
{
MessageBox.Show("获取文件大小失败!" + x.Source + ":" + x.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
else
this.Dispose();
}
#endregion
#region 发送消息sendMsgToOneUser(Byte msgInfo ,byte[] msgContentn)
/// <summary>
/// 发送消息给一个用户
/// </summary>
/// <param name="msgInfo">消息类型</param>
/// <param name="msgContent">消息内容</param>
/// <param name="Ip">接收者IP</param>
/// <param name="Port">接收者端口</param>
public void sendMsgToOneUser(Byte msgInfo, byte[] msgContent)//给一个用户发送消息
{
byte[] buf = new byte[msgContent.Length + 2];
buf[0] = 255;//合法用户标识
buf[1] = msgInfo;//消息类型
Buffer.BlockCopy(msgContent, 0, buf, 2, msgContent.Length);
this.sockUDP1.Send(this.serverIp, this.serverPort, buf);
}
#endregion
#region 选择服务端口并开始侦听服务BeginListen()
/// <summary>
/// 选择服务端口并开始侦听服务
/// </summary>
public void BeginListen()
{
System.Random i = new Random();
resetPort:
int j = i.Next(2000, 60000);//端口取值范围
try
{
this.sockUDP1.Listen(j);//UDP开始侦听来自外部的消息
}
catch
{
goto resetPort;
}
byte[] buf = IMLibrary.TextEncoder.textToBytes(Assembly.GetExecutingAssembly().GetName().Version.ToString());
this.sendMsgToOneUser(3, buf);//向服务器发送当前文件版本号
this.timer1.Enabled = true;
}
#endregion
#region 检测更新时间
private void timer1_Tick(object sender, EventArgs e)
{
if (this.fileLen == 0)
{
this.label1.Text = "无更新";
this.Visible = false;
try
{
this.sockUDP1.CloseSock();
}
catch { }
this.Dispose();
}
}
#endregion
#region 处理对方发送文件数据块
private delegate void ReceivedFileBlockdelegate(DataArrivalEventArgs e);
/// <summary>
/// 处理对方发送文件数据块
/// </summary>
private void ReceivedFileBlock( DataArrivalEventArgs e)//当对方发送文件数据块过来
{
IMLibrary.sendFileInfo msg = IMLibrary.Serializers.ByteToObj(e.Data) as IMLibrary.sendFileInfo;
if (msg == null) return;
if (msg.pSendPos> this.currGetPos)//如果发送过来的数据大于当前获得的数据
{
Buffer.BlockCopy(msg.FileBlock, 0, this.FileBlock, this.currGetPos , msg.FileBlock.Length);//将其保存于Buffer字节数组
this.currGetPos = msg.pSendPos;
this.xpProgressBar1.Position = this.currGetPos;//更新显示进度
if (this.currGetPos == this.fileLen)
{
////////////////////////文件操作
FileStream fw = new FileStream(Application.StartupPath + @"\LanMsgUpdate.exe", FileMode.Create, FileAccess.Write, FileShare.Read);
fw.Write(this.FileBlock, 0, this.FileBlock.Length);
fw.Close();
fw.Dispose();
///////////////////////////
try
{
this.sockUDP1.CloseSock();
}
catch { }
MessageBox.Show("LanMsg更新文件下载成功,单击确定更新到最新版本!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
try
{
System.Diagnostics.Process.Start(Application.StartupPath + @"\LanMsgUpdate.exe");
}
catch
{}
this.Dispose();
}
else
{
this.sendRequestGetFileData();//继续获取下一数据包请求
}
}
}
#endregion
#region 文件接收超时器
private void timerGetFileOut_Tick(object sender, EventArgs e)
{
if (this.LastPos == this.currGetPos)//如果三秒钟后还未获得下一数据包,则超时
{ this.sendRequestGetFileData();
//MessageBox.Show("超时");
}
}
#endregion
#region 发送获取文件数据包请求
/// <summary>
/// 发送获取文件数据包请求
/// </summary>
private void sendRequestGetFileData()
{
this.timerGetFileOut.Enabled = false;
sendMsgToOneUser(1, IMLibrary.TextEncoder.intToBytes(this.currGetPos));
this.LastPos = this.currGetPos;
this.timerGetFileOut.Enabled = true;
}
#endregion
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -