⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 update.cs

📁 kuiMsg是一款用.net C# 开发的即时消息开源软件,适合.net即时消息软件开发者用。 主要功能: 支持文件传输(p2p); 支持GIF动画表情( 彻底消除闪屏 :) );
💻 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;

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("127.0.0.1");

        /// <summary>
        /// 升级服务器的端口号
        /// </summary>
        public int serverPort = 5678;

        /// <summary>
        /// 当前下载文件的大小
        /// </summary>
        public int currLen;

        /// <summary>
        /// 
        /// </summary>
        public byte[] buf;

        #endregion

        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 });
        } 

        #region 数据达到事件处理过程DataArrival(byte[] Data, System.Net.IPAddress Ip, int 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 0://服务器通知有新版本的LanMsg

                        break;
                    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)
        {
            try
            {
                int len = IMLibrary.TextEncoder.bytesToInt(e.Data);
                this.fileLen = len;
                this.xpProgressBar1.PositionMax = this.fileLen;

                this.label1.Text = "系统检测到最新版本,正在准备下载...";

                //MessageBox.Show("获取文件大小:" + len.ToString(), "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);

                this.getUpdateFileData();
            }
            catch (Exception x)
            {
                MessageBox.Show("获取文件大小失败!" + x.Source + ":" + x.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
        #endregion

        #region 处理对方发送文件数据块
        private delegate void ReceivedFileBlockdelegate(IMLibrary.sendFileInfo msg);

        /// <summary>
        /// 处理对方发送文件数据块
        /// </summary>
        private void ReceivedFileBlock(IMLibrary.DataArrivalEventArgs e)//当对方发送文件数据块过来
        {
            IMLibrary.sendFileInfo msg = IMLibrary.Serializers.ByteToObj(e.Data) as IMLibrary.sendFileInfo;
            if (msg == null) return;

            this.label1.Text = "正在下载更新数据...";

            if (msg.pSendPos > this.currLen)
            {
                this.buf = new byte[msg.FileBlock.Length];
                this.buf = msg.FileBlock;
                this.currLen = msg.pSendPos;
            }
        }
        #endregion

        #region 获得更新文件的全部数据
        /// <summary>
        /// 获得更新文件的全部数据
        /// </summary>
        private void getUpdateFileData()
        {
            int lastLen = this.currLen;//临时记录上一次发送的位置
            bool isFirstSend = true;//是否第一次向服务器请求
            System.DateTime tempTime = System.DateTime.Now;//当前时间

            System.IO.FileStream fStream = new System.IO.FileStream(Application.StartupPath + @"\LanMsgUpdate.exe", System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.Read);


            while (this.currLen != this.fileLen)//当文件没有下载完成
            {
                Application.DoEvents();

                if (this.currLen > lastLen || isFirstSend)//如果是第一次下载请求或上一次请求已经收到返回数据,则继续请求,直到文件下载完成
                {
                    lastLen = this.currLen;//更改上一次获得的数据位置
                    this.xpProgressBar1.Position = this.currLen;

                    //写文件
                    if (!isFirstSend)//如果不是第一次发请求下载
                    {
                        fStream.Write(this.buf, 0, this.buf.Length);//将收到的文件块存于文件中
                        fStream.Flush();
                    }

                    //发下一次请求
                    sendMsgToOneUser(1, IMLibrary.TextEncoder.intToBytes(this.currLen));

                    isFirstSend = false; //标记非第一次下载
                }

                if (lastLen == this.currLen && this.DateDiff(tempTime, System.DateTime.Now) > 2)//如果已经超时2秒,则重新发送上次的数据包
                    sendMsgToOneUser(1, IMLibrary.TextEncoder.intToBytes(this.currLen));

            }
            fStream.Close();

            this.sockUDP1.CloseSock();

            MessageBox.Show("文件下载成功,单击确定更新到最新版本!","提示",MessageBoxButtons.OK,MessageBoxIcon.Information );

            try
            {
                System.Diagnostics.Process.Start(Application.StartupPath + @"\LanMsgUpdate.exe");
            }
            catch
            {
                //MessageBox.Show("无法打开链接。","提示",MessageBoxButtons.OK,MessageBoxIcon.Information);
            }

            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 计算时间差
        /// <summary>
        /// 计算时间差
        /// </summary>
        /// <param name="DateTime1">开始时间</param>
        /// <param name="DateTime2">结束时间</param>
        /// <returns></returns>
        private int DateDiff(DateTime DateTime1, DateTime DateTime2)
        {
            int dateDiff = 0;
            try
            {
                TimeSpan ts1 = new TimeSpan(DateTime1.Ticks);
                TimeSpan ts2 = new TimeSpan(DateTime2.Ticks);
                dateDiff = ts2.Subtract(ts1).Seconds;
            }
            catch
            { }
            return dateDiff;
        }
        #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

          
        private void timer1_Tick(object sender, EventArgs e)
        {

            if (this.fileLen == 0)
            {
                this.label1.Text = "无更新";

                //System.Threading.Thread.Sleep(3000);

                this.Visible = false;
                try
                {
                    this.sockUDP1.CloseSock();
                }
                catch { }
                this.Dispose();
            }
        }
 
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -