[朝花夕拾]基于C#的模拟仿真平台设计(部分)及服务器异步通信代码

来源:互联网 发布:java如何进行异常处理 编辑:程序博客网 时间:2024/04/30 06:28

开发环境: .net 4.5

开发语言: C#

平台架构:C-S架构

数据库: MariaDB

插件:Ribbon UI、DotNetBar

一,服务器端总体设计

根据项目需求将平台设计分为以下模块:

a)        显示信息模块

b)        用户信息管理模块

c)        配置模块

d)        与客户端通信模块

e)        数据库模块

f)         结果处理模块

g)        仿真软件控制模块

二,服务器端架构

服务器端由于两种仿真软件对操作系统的不同要求,和文件管理和数据安全方面的考虑,故使用三个服务器端,其中两个作为计算服务器,另一个作为存储服务器使用。

三,与客户端通信模块

本项目使用异步通信模式,并制定了一套通信方案,发送的信息使用UTF-8编码格式:

a)        通信内容开始符(2byte):##,识别通信内容开始

b)        通信内容大小(4byte):构造完成正文部分后填写数据包大小的int数值以验证传输数据是否正确

c)        通信内容结束符(2byte):$$,识别通信内容结束

d)        通信内容正文(不定,构造完成后确定长度)

e)        通信内容形式:命令|参数|参数|….其中参数的个数以及含义依据命令的不同来构造生成。

四,仿真软件控制模块

当客户端发出了执行仿真软件的命令时,服务器:

a)        开启一个子线程(守护线程,在服务端版Socket编程需要处理长时间没有发送数据的Socket,需要在超时多长时间后断开连接,我们需要独立一个线程(DaemonThread)来轮询,在执行断开时,需要把Socket对象锁定,并调用CloseClientSocket来断开连接)来负责处理仿真软件脚本,并将信息添加到数据库中。

b)        分别执行发送过来的几个脚本,并使用子线程监控脚本运行状态。

c)        当执行成功后将脚本文件、结果文件等相关文件上传到存储服务器,并更新数据库。

对于不能并发执行的仿真软件,设置一个脚本对象的队列。当执行脚本空闲并且队列中有脚本时,弹出第一个脚本进行执行。

五,异步通信模块代码

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Net.Sockets;using System.Net;using System.Windows.Forms;using System.Threading;using System.Data;using System.IO;namespace server2014{    public class SocketServer    {        public static string msgstr = "                     ";        // Thread signal.        public static ManualResetEvent allDone = new ManualResetEvent(false);        public SocketServer()        {            //初始化SOCKET实例            ListenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);            ListenSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);            //初始化终结点实例            localEP = new IPEndPoint(IPAddress.Any, setPort);        }        //监听网络连接的socket        public Socket ListenSocket = null;        //监听端口        public int localPort = 9999;        //监听节点        public IPEndPoint localEP = null;        //进行网络监听的线程        public Thread ListeningThread = null;        //SOCKET,用于等待其它客户端的连接        Socket server = null;        //负责与客户端进行通信的socket        Socket ClientSocket = null;        //用来设置服务端监听的端口号        public int setPort        {            get { return localPort; }            set { localPort = value; }        }        //新建线程,进行网络监听        public void startListenThread()        {            //新建一个委托线程            ThreadStart myThreadDelegate = new ThreadStart(Listen);            //实例化新线程            ListeningThread = new Thread(myThreadDelegate);            ListeningThread.IsBackground = true;            ListeningThread.Start();        }        //终止监听线程        public void stopListenThread()        {               if (ListeningThread != null)            {                 ListeningThread.Abort();            }        }        //监听函数        private void Listen()        {            setPort = 9999;            try            {                //绑定                ListenSocket.Bind(localEP);                //监听                ListenSocket.Listen(10);                //开始接受异步连接                ListenSocket.BeginAccept(new AsyncCallback(OnConnectRequest), ListenSocket);            }            catch (Exception e)            {                MessageBox.Show("开启监听服务失败!\n失败原因:" + e.Message);                Users.writeLog(MainForm.dailylogPath, DateTime.Now.ToString() + " 端口" + localPort + " 开启监听服务失败");            }        }        //当有客户端连接时的处理        public void OnConnectRequest(IAsyncResult ar)        {            string ip ="";            string ipmsgstr="";            //接收的客户端传送过来的数据            byte[] receiveData = new byte[1024];            byte[] senddata = null;            try            {                //初始化一个SOCKET,用于等待其它客户端的连接                server = (Socket)ar.AsyncState;                server.BeginAccept(new AsyncCallback(OnConnectRequest), server);                //负责与客户端进行通信的socket                ClientSocket = server.EndAccept(ar);                //获取客户端的IP和端口                ip = ClientSocket.RemoteEndPoint.ToString();                ipmsgstr = ip + "                           ";            }            catch            {                MainForm.mainfrm.messageShow(DateTime.Now.ToString() + msgstr + ipmsgstr + "网络错误!" + "\r\n");            }            //负责接收客户端信息            while (true)            {                int recv = 0;                try                {                    recv = ClientSocket.Receive(receiveData);                    //对传输过来的数据进行解析                    byte[] effemsg = Protocol.SubByteArray(receiveData, 0, recv);                    string[] parameters = Protocol.anaMsg(effemsg);                    int per = 0;//判断权限                    int[] perpass = { 0, 0 };                    //根据协议命令的不同进行不同的处理                    switch (parameters[0])                    {                        case "-1":                            //协议解析出错,断开连接                            try                            {                                //断开连接                                ClientSocket.Disconnect(true);                                MainForm.mainfrm.messageShow(DateTime.Now.ToString() + msgstr + ipmsgstr + "与客户端断开连接! " + "\r\n");                                return;                            }                            catch (Exception e)                            {                                MainForm.mainfrm.messageShow(DateTime.Now.ToString() + msgstr + ipmsgstr + "网络错误!" + "\r\n");                                return;                            }                        case "0":                            //查看服务器端执行的所有任务                            perpass = Business.check(parameters[1], parameters[2]);                            per = perpass[1];                            if (perpass[0] > 0)                            {                                //用户名密码验证成功则添加用户                                //Business.addUser(parameters[1], parameters[2]);                                Business.loginUser(parameters[1], parameters[2]);                                string sendstring = Business.getAllTasks();                                senddata = Protocol.getLookReturnMsg(sendstring);                                try                                {                                    MainForm.mainfrm.messageShow(DateTime.Now.ToString() + msgstr + ipmsgstr + "用户" + parameters[1] + "查看服务器运行状况。" + "\r\n");                                    ClientSocket.Send(senddata);                                }                                catch (Exception e)                                {                                    MainForm.mainfrm.messageShow(DateTime.Now.ToString() + msgstr + ipmsgstr + "网络错误!" + e.Message + "\r\n");                                }                            }                            else                            {                                MainForm.mainfrm.messageShow(DateTime.Now.ToString() + msgstr + ipmsgstr + "用户" + parameters[1] + "查看服务器运行状况时密码验证失败!" + "\r\n");                                senddata = Protocol.getCheckReturnMsg(parameters[1], per.ToString(), false);                                try                                {                                    ClientSocket.Send(senddata);                                }                                catch (Exception e)                                {                                    MainForm.mainfrm.messageShow(DateTime.Now.ToString() + msgstr + ipmsgstr + "网络错误!" + e.Message + "\r\n");                                }                            }                            break;                        case "1":                            //验证客户端用户名密码                            perpass = Business.check(parameters[1], parameters[2]);                            per = perpass[1];                            if (perpass[0] > 0)                            {                                MainForm.mainfrm.messageShow(DateTime.Now.ToString() + msgstr + ipmsgstr + "用户" + parameters[1] + "登录成功!" + "\r\n");                                Users.writeLog(MainForm.dailylogPath, DateTime.Now.ToString() + " " + ip + " 用户 " + parameters[1] + " 登录成功!");                                LoginForm.users.ftpupdown.MakeDir(parameters[1]);                                //用户名密码验证成功则添加用户                                //Business.addLoginUser(parameters[1]);                                //Business.addUser(parameters[1], parameters[2]);                                Business.loginUser(parameters[1], parameters[2]);                                string serveru = Config.getparameter("Serveru");                                string ansysPath = Config.getparameter("ansysProgramPath");                                DatabaseTools db = Users.databaseTools4;                                List<string> tasklist = new List<string>();                                string userpath = Users.ftpServerpath + "\\" + parameters[1];                                Users.creatDirtionary(userpath);                                db.queryTaskByUsername(parameters[1], tasklist);                                foreach (string taskname in tasklist)                                {                                    string taskpath = userpath + "\\" + taskname;                                    Users.creatDirtionary(taskpath);                                    for (int i = 1; i < 4; i++)                                    {                                        //i为脚本类型                                        string kindpath = taskpath + "\\" + Users.scriptKindTrans(i);                                        Users.creatDirtionary(kindpath);                                        List<string> scriptsList = new List<string>();                                        Users.databaseTools.queryScriptByUserTaskname(parameters[1], taskname, i, 3, scriptsList);                                        foreach (string scriptname in scriptsList)                                        {                                            string scriptpath = kindpath + "\\" + scriptname;                                            Users.creatDirtionary(scriptpath);                                            string sciptfilepath = scriptpath + "\\script";                                            Users.creatDirtionary(sciptfilepath);                                            string scipttemppath = scriptpath + "\\temp";                                            Users.creatDirtionary(scipttemppath);                                            string sciptresultpath = scriptpath + "\\result";                                            Users.creatDirtionary(sciptresultpath);                                        }                                    }                                }                                List<string> taskAndUpdateList = new List<string>();                                db.queryTaskAndUpdateByUsername(parameters[1], taskAndUpdateList);                                senddata = Protocol.getLoginCheckReturnMsg(parameters[1], serveru,ansysPath, taskAndUpdateList, per.ToString(), true);                                //将客户端查询时间记录到txt文本中                                foreach (string taskname in tasklist)                                {                                    string taskpath = userpath + "\\" + taskname;                                    Users.writeClientLogin(taskpath + "\\taskLastQuery.txt", DateTime.Now.ToString());                                }                                try                                {                                    ClientSocket.Send(senddata);                                }                                catch (Exception e)                                {                                    MainForm.mainfrm.messageShow(DateTime.Now.ToString() + msgstr + ipmsgstr + "网络错误!" + e.Message + "\r\n");                                }                            }                            else                            {                                MainForm.mainfrm.messageShow(DateTime.Now.ToString() + msgstr + ipmsgstr + "用户" + parameters[1] + "登录失败!" + "\r\n");                                //senddata = Protocol.getCheckReturnMsg(parameters[1], per.ToString(),false);                                senddata = Protocol.getLoginCheckReturnMsg(parameters[1], "","", new List<string>(), per.ToString(), false);                                try                                {                                    ClientSocket.Send(senddata);                                }                                catch (Exception e)                                {                                    MainForm.mainfrm.messageShow(DateTime.Now.ToString() + msgstr + ipmsgstr + "网络错误!" + e.Message + "\r\n");                                }                            }                            break;                        case "2":                            //添加新的脚本并且执行                            Business.loginUser(parameters[1], parameters[2]);                            MainForm.mainfrm.messageShow(DateTime.Now.ToString() + msgstr + ipmsgstr + "用户" + parameters[1] + "执行任务" + parameters[3] + "的脚本程序" + parameters[4] + "\r\n");                            try                            {                                //将新的任务保存到USERS中                                LoginForm.users.addTask(parameters[1], parameters[3]);                                LoginForm.users.addScript(parameters[1], parameters[3], parameters[4], int.Parse(parameters[5]));                                //执行新的任务,执行脚本                                //------------------------------------------------------------------                                bool executeflag = false; //执行是否成功                                //执行脚本的总次数                                int projectcount = int.Parse(parameters[6]);                                 //当前执行脚本的数量                                int projecttemp = 0;                                if (int.Parse(parameters[5]) == 2)                                {                                    Users.databaseTools.updateScriptState(parameters[1], parameters[3], parameters[4], 2);                                    string xmlpath = Users.ftpServerpath + "\\" + parameters[1] + "\\" + parameters[3] + "\\test\\" + parameters[4] + "\\" + parameters[4] + ".xml";                                    string curxmlpath = Users.ftpServerpath + "\\" + parameters[1] + "\\" + parameters[3] + "\\test\\" + parameters[4] + "\\temp\\" + parameters[4] + ".xml";                                    File.Copy(curxmlpath, xmlpath, true);                                    for (; projecttemp < projectcount; projecttemp++)                                    {                                        executeflag = Business.executeScript(parameters[1], parameters[3], parameters[4], int.Parse(parameters[5]), projecttemp, projectcount);                                        Thread.CurrentThread.Join(1000);                                    }                                }                                else if (int.Parse(parameters[5]) == 1)                                {                                    executeflag = Business.executeScript(parameters[1], parameters[3], parameters[4], int.Parse(parameters[5]), projecttemp, projectcount);                                }                                else if (int.Parse(parameters[5]) == 3)                                {                                    executeflag = Business.executeScript(parameters[1], parameters[3], parameters[4], int.Parse(parameters[5]), projecttemp, projectcount);                                    //更改脚本状态为运行                                    Users.databaseTools.updateScriptState(parameters[1], parameters[3], parameters[4], 2);                                }                                //------------------------------------------------------------------                                //bool executeflag = Business.executeScript(parameters[1], parameters[3], parameters[4], int.Parse(parameters[5]));                                //Users.checkAddsettings();                                senddata = Protocol.getExecuteReturnMsg(parameters[1], parameters[3], parameters[4], executeflag);                            }                            catch (Exception e)                            {                                MainForm.mainfrm.messageShow(DateTime.Now.ToString() + msgstr + ipmsgstr + "用户" + parameters[1] + "执行任务" + parameters[3] + "的脚本程序" + parameters[4] + "错误!\r\n");                            }                            try                            {                                ClientSocket.Send(senddata);                            }                            catch (Exception e)                            {                                MainForm.mainfrm.messageShow(DateTime.Now.ToString() + msgstr + ipmsgstr + "网络错误!" + e.Message + "\r\n");                            }                            break;                        case "3":                            //查询某一任务中某一个脚本的状态                            Business.loginUser(parameters[1], parameters[2]);                            //查询任务下某一脚本状态                            MainForm.mainfrm.messageShow(DateTime.Now.ToString() + msgstr + ipmsgstr + "用户" + parameters[1] + "查询任务" + parameters[3] + "的脚本程序" + parameters[4] + "的执行状态。\r\n");                            //查询任务之中某一个脚本的状态                            scriptStates scriptstate = LoginForm.users.queryScriptState(parameters[1], parameters[3], parameters[4], int.Parse(parameters[5]));                            //返回任务状态                            senddata = Protocol.getQueryReturnMsg(parameters[1], parameters[3], parameters[4], scriptstate.ToString(), parameters[5]);                            try                            {                                ClientSocket.Send(senddata);                            }                            catch (Exception e)                            {                                MainForm.mainfrm.messageShow(DateTime.Now.ToString() + msgstr + ipmsgstr + "网络错误!" + e.Message + "\r\n");                            }                            break;                        case "4":                            //删除某一任务的执行                            Business.loginUser(parameters[1], parameters[2]);                            //删除任务                            int deleteflag = Users.databaseTools4.deleteTask(parameters[1], parameters[2]);                            if (deleteflag > 0)                            {                                MainForm.mainfrm.messageShow(DateTime.Now.ToString() + msgstr + ipmsgstr + "用户" + parameters[1] + "删除任务" + parameters[2] + "成功。\r\n");                            }                            else                            {                                MainForm.mainfrm.messageShow(DateTime.Now.ToString() + msgstr + ipmsgstr + "用户" + parameters[1] + "删除任务" + parameters[2] + "失败。\r\n");                            }                            //返回任务状态                            senddata = Protocol.getTdeleteReturnMsg(parameters[1], parameters[2], deleteflag.ToString());                            try                            {                                ClientSocket.Send(senddata);                            }                            catch (Exception e)                            {                                MainForm.mainfrm.messageShow(DateTime.Now.ToString() + msgstr + ipmsgstr + "网络错误!" + "\r\n");                            }                            break;                        case "5":                            Business.loginUser(parameters[1], parameters[2]);                            MainForm.mainfrm.messageShow(DateTime.Now.ToString() + msgstr + ipmsgstr + "用户" + parameters[1] + "查询任务" + parameters[3] + "下脚本信息。\r\n");                            //任务                            DataTable dt1 = Users.queryScriptMessage(parameters[1], parameters[3], new string[] { "scriptname", "scriptkind", "scriptstate" });                            bool queryTaskFlag = true;                            //返回任务状态                            senddata = Protocol.getQueryTaskReturnMsg(parameters[1], parameters[3], dt1, queryTaskFlag);                            try                            {                                ClientSocket.Send(senddata);                            }                            catch (Exception e)                            {                                MainForm.mainfrm.messageShow(DateTime.Now.ToString() + msgstr + ipmsgstr + "网络错误!" + "\r\n");                            }                            break;                        case "6":                            if (int.Parse(parameters[1]) == 1)                            {                                Users.databaseTools4.addMaterial(parameters[3], parameters[4], parameters[5], parameters[6], parameters[7], parameters[8], parameters[9], parameters[10], parameters[11], parameters[12], parameters[13], parameters[14], parameters[15], parameters[16], parameters[17], parameters[18], parameters[19], parameters[20]);                                MainForm.mainfrm.messageShow(DateTime.Now.ToString() + msgstr + ipmsgstr + "用户" + parameters[1] + "添加材料" + parameters[3] + "。\r\n");                            }                            else if (int.Parse(parameters[1]) == 2)                            {                                Users.databaseTools4.deleteMaterial(parameters[2]);                                MainForm.mainfrm.messageShow(DateTime.Now.ToString() + msgstr + ipmsgstr + "用户" + parameters[1] + "删除材料" + parameters[2] + "。\r\n");                            }                            else if (int.Parse(parameters[1]) == 3)                            {                                Users.databaseTools4.updateMaterial(parameters[2], parameters[3], parameters[4], parameters[5], parameters[6], parameters[7], parameters[8], parameters[9], parameters[10], parameters[11], parameters[12], parameters[13], parameters[14], parameters[15], parameters[16], parameters[17], parameters[18], parameters[19], parameters[20]);                                MainForm.mainfrm.messageShow(DateTime.Now.ToString() + msgstr + ipmsgstr + "用户" + parameters[1] + "修改材料" + parameters[3] + "。\r\n");                            }                            else if (int.Parse(parameters[1]) == 4)                            {                                MainForm.mainfrm.messageShow(DateTime.Now.ToString() + msgstr + ipmsgstr + "用户" + parameters[1] + "查询材料。\r\n");                            }                            DataTable dt = new DataTable();                            Users.databaseTools4.queryMaterial(0 + "", dt);                            //dt.Rows[0][1];                            senddata = Protocol.getMaterialReturnMsg(dt);                            try                            {                                ClientSocket.Send(senddata);                            }                            catch (Exception e)                            {                                MainForm.mainfrm.messageShow(DateTime.Now.ToString() + msgstr + ipmsgstr + "网络错误!" + "\r\n");                            }                            break;                    }                }                catch (SocketException e)                {                    MainForm.mainfrm.messageShow(DateTime.Now.ToString() + msgstr + ipmsgstr + "网络错误! " + "\r\n");                    return;                }                finally                {                }            }        }    }}

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 去泰国护照怎么办签证 护照出来了怎么办签证? 有护照怎么办旅游签证 机票护照号写错了怎么办 美国护照过期了怎么办 护照过期十年了怎么办 护照期限到期了怎么办 签证超出停留期怎么办 签证快过期了怎么办 去国外旅游签证怎么办 照片回执过期了怎么办 加拿大护照丢了怎么办 头发有颜色怎么办护照 微信怎么办港澳通行证 港澳通行证 团签怎么办 出境章没有盖怎么办 过海关没有盖章怎么办 中国入境没盖章怎么办 护照有效期写错怎么办 回国海关电子盖章怎么办 户籍在学校怎么办护照 割过双眼皮护照怎么办 想换电子护照怎么办 有美签的护照丢失怎么办 护照在国外掉了怎么办 上海动迁房户口怎么办 政府强制拆房怎么办 农村无证宅基地怎么办 身份证没磁怎么办护照 买安置房怎么办产权 安置房房东违约怎么办 安置房产权到期怎么办 安置房怎么办房产证吗 美甲后指甲长了怎么办 在菲律宾怎么办持枪证? 绝地求生打不准怎么办 身份证号码变更后社保怎么办 社保与身份不符怎么办 年龄改了学籍怎么办 结婚证信息错误怎么办 六级身份证过期怎么办