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

📄 servicemain.cs

📁 kuiMsg是一款用.net C# 开发的即时消息开源软件,适合.net即时消息软件开发者用。 主要功能: 支持文件传输(p2p); 支持GIF动画表情( 彻底消除闪屏 :) );
💻 CS
字号:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;
using System.IO;
using IMLibrary;
using System.Data.SqlClient;

namespace LanMsgUpdateService
{
    public partial class ServiceMain : ServiceBase
    {
        public ServiceMain()
        {
            InitializeComponent();
        }

        #region 用户变量区域
        /// <summary>
        /// 服务器侦听端口
        /// </summary>
        private int ListenPort = 5678;

        /// <summary>
        /// 升级文件的字节数组
        /// </summary>
        byte[] fileBuf;

        /// <summary>
        /// 文件长度
        /// </summary>
        byte[] fileLen;

        /// <summary>
        /// 文件名
        /// </summary>
        string FileName = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "LanMsgUpdate.exe";

        /// <summary>
        /// 客户端最新文件版本号
        /// </summary>
        string version = "1.0.0.1";

        /// <summary>
        /// 最大网络传输单元
        /// </summary>
        uint  MTU = 1000;

        #endregion

        #region 服务启动与停止
        protected override void OnStart(string[] args)
        {
            this.version =LanMsgUpdateService.Settings1.Default.Version;
            this.MTU = LanMsgUpdateService.Settings1.Default.MTU;
            this.stratListen();//当WINDOWS SERVICE启动时开始侦听来自客户端的请求
        }

        protected override void OnStop()
        {
            this.stopServer();
         }
        #endregion

        #region 当WINDOWS SERVICE启动时开始侦听来自客户端的请求
        /// <summary>
        /// 开始侦听来自客户端的请求
        /// </summary>
        private void stratListen() 
        {
            try
            {
                this.sockUDP1.Listen(ListenPort);
                if (this.readUpdateFile())
                    this.WirteLog("服务启动成功,升级文件版本号:"+ this.version +",升级数据大小:"+ this.fileBuf.Length.ToString()  +"字节,最大网络传输单元MTU="+ this.MTU.ToString ());
                else
                    this.WirteLog("文件初始化失败");
            }
            catch
            {
                this.WirteLog("服务启动失败");
            }
        }
        #endregion
       
        #region 停止当前WINDOWS SERVICE时关闭sock的侦听,释放占用的端口资源,防止下次启动服务时系统发生错误
        private void stopServer ()
        {
            try
            {
                this.sockUDP1.CloseSock ( );
                this.fileBuf = null;
                this.WirteLog("服务停止成功");
            }
            catch
            {
                this.WirteLog("服务停止失败");
            }
        }
        #endregion
         

        private void sockUDP1_DataArrival(byte[] Data, System.Net.IPAddress Ip, int Port)//UDP数据到达事件
        {
             this.DataArrival(Data, Ip, Port);
        }

 
        private void DataArrival(byte[] Data, System.Net.IPAddress Ip, int Port) //当有数据到达后的处理过程
        {

            if (Data[0] != 255) return;//将非法用户的数据抛弃

            int cnt = 0;//记录接收到的数据包大小

            cnt = Data.Length;//获取接收到的数据包大小

            if (cnt < 3) return;//如果收到的数据小于3,个字节则视为非法用户抛弃

            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.sendFileData(new DataArrivalEventArgs(buffer,Ip,Port));
                        break;

                    case 2://用户要求获得升级文件包的大小
                        this.sendFileLen(new DataArrivalEventArgs(Ip, Port));
                        break;

                    case 3://判断文件版本号
                        this.getVersion(new DataArrivalEventArgs(buffer, Ip, Port));
                        break;
                }
            }
            catch
            {
                this.WirteLog("系统收到数据无法识别的消息类型。非法用户--"+ Ip.ToString() +":"+ Port.ToString());
            }
        }

        #region 获得客户端版本号
        /// <summary>
        /// 获得客户端版本号
        /// </summary>
        /// <param name="e"></param>
        private void getVersion(DataArrivalEventArgs e)
        {
            string Version =this.version ;
            try
            {
                Version = TextEncoder.bytesToText(e.Data);//获得客户端文件版本号
            }
            catch { this.WirteLog("错误的版本数据!"); };
            if (this.version != Version)//如果有最新版本,则告诉用户升级
            {
                this.sendFileLen(e);//向用户发送升级包数据大小
            }
        }
        #endregion

        #region 向用户发送升级包数据大小
        /// <summary>
        /// 向用户发送升级包数据大小
        /// </summary>
        /// <param name="e"></param>
        private void sendFileLen(DataArrivalEventArgs e)
        {
            this.sendMsgToOneUser(2, this.fileLen, e.IP, e.Port);
        }
        #endregion

        #region 向用户发送升级包数据
        /// <summary>
        /// 向用户发送升级包数据
        /// </summary>
        /// <param name="e"></param>
        private void sendFileData(DataArrivalEventArgs e)
        {
            int currPos = IMLibrary.TextEncoder.bytesToInt(e.Data);//获得要发送文件的起始位置
            if (currPos >= this.fileBuf.Length) return;

            byte[] buffer = new byte[this.MTU];//要发送的缓冲区

            if (currPos + this.MTU > this.fileBuf.Length)//如果发送
                buffer = new byte[this.fileBuf.Length - currPos];

            Buffer.BlockCopy(this.fileBuf, currPos, buffer, 0, buffer.Length );//将其保存于Buffer字节数组

            IMLibrary.sendFileInfo fileInfo = new sendFileInfo(1,currPos + buffer.Length ,buffer );

            this.sendMsgToOneUser(1, IMLibrary.Serializers.ObjToByte(fileInfo), e.IP, e.Port);
        }
        #endregion

        #region 升级文件数据初始化
        /// <summary>
        /// 升级文件数据初始化
        /// </summary>
        /// <returns></returns>
        private bool  readUpdateFile()
        {

            System.IO.FileInfo f = new FileInfo(FileName);
            if (!f.Exists) return false;

            int fileLen =(int ) f.Length;

            this.fileBuf = new byte[fileLen];

            System.IO.FileStream fStream = new System.IO.FileStream(f.FullName, FileMode.Open, FileAccess.Read, FileShare.Read);
            int ReadCount = fStream.Read(this.fileBuf, 0, fileLen);//将要发送的文件块数据存入发送缓冲区
            fStream.Close();

            if (ReadCount != fileLen)
                return false;
            else
            {
                this.fileLen = IMLibrary.TextEncoder.intToBytes (this.fileBuf.Length) ;//将文件大小存入字节数组
                return true;
            }
        }
        #endregion

        #region 发送消息给一个用户sendMsgToOneUser(Byte msgInfo ,byte[] msgContent, System.Net.IPAddress Ip, int Port)
        /// <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, System.Net.IPAddress Ip, int Port)//给一个用户发送消息 
        {
            byte[] buf = new byte[msgContent.Length + 2];
            buf[0] = 255;//合法用户标识
            buf[1] = msgInfo;//消息类型
            Buffer.BlockCopy(msgContent, 0, buf, 2, msgContent.Length);
            IMLibrary.SockUDP sockTemp = new  SockUDP();
            sockTemp.Send(Ip, Port, buf);
            sockTemp.Dispose();
        }
        #endregion

        #region 将消息写入日志文件 WirteLog(string str)
        /// <summary>
        /// LanMsg写日志函数
        /// </summary>
        /// <param name="str">要写入的日志内容字符串</param>
        private void WirteLog(string str)  
        {
            FileStream fs = new FileStream(AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "log.txt", FileMode.OpenOrCreate, FileAccess.Write);
            StreamWriter _streamWriter = new StreamWriter(fs);
            _streamWriter.BaseStream.Seek(0, SeekOrigin.End);
            _streamWriter.WriteLine(str + " " + DateTime.Now.ToString() + "\n");
            _streamWriter.Flush();
            _streamWriter.Close();
            fs.Close();
        }
        #endregion
    }
}

⌨️ 快捷键说明

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