using Lskj.Business; using Lskj.Business.Impl; using Lskj.Core; using Lskj.Model; using Lskj.Util; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.IO; using System.Linq; using System.Net; using System.Net.Sockets; using System.ServiceProcess; using System.Text; using System.Threading; using System.Threading.Tasks; namespace ServerNotice { public partial class Service : ServiceBase { public Service() { InitializeComponent(); } private Thread mainThread; public System.Timers.Timer Timer = new System.Timers.Timer(); public System.Timers.Timer timer = new System.Timers.Timer(); /// public string DataAddress = string.Empty; public string DataName = string.Empty; public string Port = string.Empty; ///获取本地的IP地址 public string AddressIP = string.Empty; /// /// 旧的数据源存储 /// public DataTable oldData = new DataTable(); Socket sck = null; //Thread thread = null; /// /// 初始化界面的本机ip地址值和端口 /// private void IniControl() { try { foreach (IPAddress _IPAddress in Dns.GetHostEntry(Dns.GetHostName()).AddressList) { if (_IPAddress.AddressFamily.ToString() == "InterNetwork") { //AddressIP = "192.168.0.240"; AddressIP = _IPAddress.ToString(); string dataAddre = IniHelper.Read("MenuConfig.ini", "MenuConfig", string.Format("Server_{0}", AddressIP)); string[] dataAddress = dataAddre.Split('^'); if (dataAddress.Length == 3) { DataAddress = dataAddress[0]; DataName = dataAddress[1]; Port = dataAddress[2]; WriteLog(DataAddress + "_" + DataName); break; } } } } catch (Exception ex) { WriteLog("错误信息:" + ex.Message); } } //点击开启服务端监听 //private void btn_StarServer_Click(object sender, EventArgs e) //{ // LoadStartServer(); //} /// /// 建立soket数据方法 /// public void LoadStartServer() { try { DBConfig.Instance.ServerName = DataAddress; DBConfig.Instance.DataBase = DataName; if (DBConfig.Instance.CreateConnection()) { //创建一个Socket实例 //第一个参数表示使用ipv4 //第二个参数表示发送的是数据流 //第三个参数表示使用的协议是Tcp协议 sck = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //获取ip地址 IPAddress ip = IPAddress.Parse(AddressIP); //创建一个网络通信节点,这个通信节点包含了ip地址,跟端口号。 //这里的端口我们设置为1029,这里设置大于1024,为什么自己查一下端口号范围使用说明。 IPEndPoint endpoint = new IPEndPoint(ip, Convert.ToInt32(string.IsNullOrEmpty(Port) ? "8080" : Port));//创建一个网络通信节点,该节点中包含了IP地址和端口号. //this.portBox.Text = endpoint.ToString(); //Socket绑定网路通信节点 WriteLog("端口:" + endpoint + ""); sck.Bind(endpoint); //设置监听队列 sck.Listen(10); WriteLog("开启监听!"); //ShowMsg("开启监听!"); this.timer.Enabled = true; //开启一个线程,放入Socket服务监听,上一篇博文中没有介绍这样的线程实例化方法。这里特别说下这样是可以的。 Thread thread = new Thread(ConnectAccept); //设置为后台线程 thread.IsBackground = true; thread.Start(); //IniHelper.Write("Server_" + AddressIP, DataAddress + "^" + DataName); } else { WriteLog("错误信息:数据库连接失败!"); } } catch (Exception ex) { WriteLog("错误信息:" + ex.Message); } } /// /// 判断是否有差异 /// /// /// /// public DataTable CompareTwoDataTable(DataTable dt1, DataTable dt2) { dt1.Merge(dt2); DataTable dt3 = dt2.GetChanges(); return dt3; } //消息框里面数据 //void ShowMsg(string str) //{ // string Ystr = ""; // if (txt_AccMsg.Text != "") // { // Ystr = txt_AccMsg.Text + "\r\n"; // } // txt_AccMsg.Text = Ystr + str; //} //向客户端发送数据 private void btn_SendSingleMsg_Click(object sender, EventArgs e) { SendSingleMsg(); } public void SendSingleMsg(string msg = "", string IpsName = "") { try { IpsName = string.IsNullOrEmpty(IpsName) ? "" : IpsName; string sendMsg = string.IsNullOrEmpty(msg) ? "" : msg;//获取要发送到客户端的文本 byte[] buffer = System.Text.Encoding.UTF8.GetBytes(sendMsg);//生成字节数组 if (!string.IsNullOrEmpty(IpsName)) { string ipendpoint = IpsName;//在服务端,选择与客户端进行通信的IP地址与端口号 socketDir[ipendpoint].Send(buffer);//向客户端发送数据 //ShowMsg("向客户端发送了:" + "成功!"); } else { //MessageBox.Show("请选择与哪个客户端进行通信"); } } catch (Exception ex) { WriteLog("错误信息:" + ex.Message); } } // Socket newSoket = null;//.:不能将与客户端进行通信的Socket定义成全局的. Dictionary socketDir = new Dictionary();//将每一个与客户端进行通信的Socket放到该集合中. Dictionary socketStrDir = new Dictionary();//将每一个与客户端进行通信的userid和NAME放到该集合中. public void ConnectAccept() { try { while (true)//注意该循环,服务端要持续监听 { Socket newSoket = sck.Accept();//接收客户端发过来的数据,并且创建了一个新的Socket实例. socketDir.Add(newSoket.RemoteEndPoint.ToString(), newSoket);//将负责与客户端进行通信的Socket实例添加到集合中。 //lsb_Ips.Items.Add(newSoket.RemoteEndPoint.ToString()); //ShowMsg("客户端链接成功!"); ParameterizedThreadStart par = new ParameterizedThreadStart(RecevieMsg); Thread thread = new Thread(par);//由于服务端接收客户端发送过来的数据是通过Recevie方法,该方法会阻断线程,所以我们重新定义一个针对该方法的线程. // thread.SetApartmentState(ApartmentState.STA); thread.IsBackground = true; thread.Start(newSoket);//注意:不要忘记传递socket实例 } } catch (Exception ex) { } } //该方法负责接收从客户端发送过来的数据 public void RecevieMsg(object socket) { Socket newSocket = socket as Socket;//转成对应的Socket类型 while (true) { byte[] buffer = new byte[1024 * 1024 * 2]; int receiveLength = -1; try //由于Socket中的Receive方法容易抛出异常,所以我们在这里要捕获异常。 { receiveLength = newSocket.Receive(buffer);//接收从客户端发送过来的数据 } catch (SocketException ex)//注意:在捕获异常时,先确定具体的异常类型。 { //ShowMsg("出现了异常:" + ex.Message); socketDir.Remove(newSocket.RemoteEndPoint.ToString());//如果出现了异常,将该Socket实例从集合中移除 //lsb_Ips.Items.Remove(newSocket.RemoteEndPoint.ToString()); socketStrDir.Remove(newSocket.RemoteEndPoint.ToString()); WriteLog(string.Format("{0}已断开连接", newSocket.RemoteEndPoint.ToString())); break;//出现异常以后,终止整个循环的执行 } catch (Exception ex) { //ShowMsg("出现了异常:" + ex.Message); break; } if (buffer[0] == 0 && receiveLength > 1)//表示字符串 { string str = System.Text.Encoding.UTF8.GetString(buffer, 1, receiveLength - 1);//注意,是从下标为1的开始转成字符串,为0的是标识。 WriteLog(string.Format("接收到{0}数据:{1}", newSocket.RemoteEndPoint.ToString(), str)); socketStrDir.Add(newSocket.RemoteEndPoint.ToString(), str); //ShowMsg(str); } else if (buffer[0] == 1)//表示文件 { //SaveFileDialog savafile = new SaveFileDialog(); //if (savafile.ShowDialog() == DialogResult.OK) //{ // using (FileStream fs = new FileStream(savafile.FileName, FileMode.Create)) // { // fs.Write(buffer, 1, receiveLength - 1);//将文件写到磁盘上,从1开始到receiveLength-1 // ShowMsg("文件写成功!"); // } //} } } } /// /// 循环查询数据库获取更新数据 /// /// /// private void OnTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { try { this.timer.Enabled = false; DBConfig.Instance.ReadConfig(); DBConfig.Instance.ServerName = DataAddress; DBConfig.Instance.DataBase = DataName; DBConfig.Instance.CreateConnection(); //ERPInfo.Instance.UserId = DBConfig.Instance.NoticeUserID; //ERPInfo.Instance.UserName = DBConfig.Instance.NoticeUserName; //DataTable data = NoticeImpl.GetNoticeData2(ERPInfo.Instance.UserId); //foreach (string item in lsb_Ips.Items) //{ // SendSingleMsg(data.ToJsonArray(), item); //} foreach (string key in socketStrDir.Keys) { ERPInfo.Instance.UserId = socketStrDir[key].Split(',')[0]; ERPInfo.Instance.UserName = socketStrDir[key].Split(',')[1]; string SqlStr = ""; DataTable data = NoticeImpl.GetNoticeData2(ERPInfo.Instance.UserId, out SqlStr); data = SqlHelper.ExecuteDataTable(SqlStr); SendSingleMsg(data.ToJsonArray(), key); //WriteLog(string.Format("UserId:{0}已从数据库{1}:{2}获取到{3}条数据,发送数据到:{4},连接:{5}", ERPInfo.Instance.UserId, DataAddress, DataName, data.Rows.Count + "", key, SqlHelper._connection.ConnectionString)); } } catch (Exception) { } finally { this.timer.Enabled = true; } } private void StartMethod(object args) { this.IniControl();//初始化服务界面本机的地址值 string[] Args = args as string[]; if (Args != null && Args.Length > 0) LoadStartServer(); this.timer.Elapsed += OnTimer_Elapsed; this.timer.Interval = 10000; LoadStartServer(); } private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { try { this.Timer.Enabled = false; if (mainThread == null)//mainThread.ThreadState == System.Threading.ThreadState.Aborted { ParameterizedThreadStart par = new ParameterizedThreadStart(StartMethod); mainThread = new Thread(par); mainThread.IsBackground = true; mainThread.Start(); } else if (false) { mainThread.Abort(); mainThread = null; ParameterizedThreadStart par = new ParameterizedThreadStart(StartMethod); mainThread = new Thread(par); mainThread.IsBackground = true; mainThread.Start(); } } catch (Exception) { } finally { this.Timer.Enabled = true; } } private void WriteLog(string message) { try { string path = Path.Combine(Lskj.Util.PubUtil.AbsolutelyPath + "LogFile.log"); if (File.Exists(path)) { FileInfo fileInfo = new FileInfo(path); if (fileInfo.Length > 1024 * 10) { fileInfo.Delete(); } } if (!Directory.Exists(Path.GetDirectoryName(path))) Directory.CreateDirectory(Path.GetDirectoryName(path)); if (!File.Exists(path)) File.Create(path); StreamWriter writer = File.AppendText(path); writer.WriteLine(""); writer.WriteLine(DateTime.Now.ToString("日志记录HH:mm:ss") + " " + message + " "); writer.Flush(); writer.Close(); } catch (Exception) { } } protected override void OnStart(string[] args) { try { //Debugger.Launch(); ParameterizedThreadStart par = new ParameterizedThreadStart(StartMethod); mainThread = new Thread(par); mainThread.Start(args); //this.Timer.Interval = 10000; //this.Timer.Elapsed += Timer_Elapsed; //this.Timer.Enabled = true; } catch (Exception) { } } protected override void OnStop() { } } }