自己写的TCP监听器

宿主是自己写的winform窗体程序,这个监听器跑在后台线程,用户开启监听后,仍然可以在界面进行其他操作

勾选checkbox,启动监听器,事件如下:

private void ckbStartListen_CheckedChanged(object sender, EventArgs e)
        {
            
            int port = 0;
            if (!int.TryParse(tbServerPort.Text.Trim(), out port) && ckbStartListen.Checked)
            {
                MessageBox.Show("监听端口填写错误");
                tbServerPort.Focus();
                ckbStartListen.Checked = false;

                return;
            }
            //勾选启动监听并且线程不忙时,可以开启监听
            if (ckbStartListen.Checked)
            {
                if (backgroundWorker1.IsBusy)
                {
                    MessageBox.Show("线程正忙,请稍后再试");
                    ckbStartListen.Checked = false;
                    return;
                }

                
                backgroundWorker1.RunWorkerAsync(port);
                label16.Text = "正在监听";
                label16.ForeColor = Color.Green;
                tbServerPort.Enabled = false;
            }
            else
            {
                try
                {
                    if (backgroundWorker1.IsBusy)
                    {
                        //停止
                        backgroundWorker1.CancelAsync();

                        label16.Text = "正在断开连接,请等待几秒";
                        label16.ForeColor = Color.Red;
                        //给自己发一个连接,以通知异步线程停止监听
                        TcpClient client = new TcpClient();

                        string hostName = Dns.GetHostName();

                        client.Connect(IPAddress.Parse("127.0.0.1"), port);

                        if (client.Connected)
                            client.Close();

                       
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }

            }
        }

后台线程backgroundWorker1的各个事件

 private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            //进度报告
            tbReportInfo.Text = string.Join("\r\n", Reports);
            tbSuccessNum.Text = PKSuccess.ToString();
            tbFailNum.Text = PKFail.ToString();
            tbUploadTime.Text = (PKFail + PKSuccess).ToString();
            tbServerPort.Enabled = false;

            if (!string.IsNullOrEmpty(DevState))
                tbDevState.Text = DevState;
            if (!string.IsNullOrEmpty(DoorState))
                tbDoorState.Text = DoorState;

            tbWallShake.Text = KBAlert+"";
            tbDoorShake.Text = KMAlert+"";
            tbOutTime.Text = OutTimeAlert+"";

            //dgvPKinfo.DataSource = null;
            //dgvPKinfo.DataSource = pklist;
            //必须这样绑定才能刷新列表,晕
            dgvPKinfoRef();
            dgvLockInfoRef();
            dgvJCRef();
            //dgvLockInfo.DataSource = lockList;
            //dgvJC.DataSource = cjShowlist;
        }
        private void dgvPKinfoRef()
        {
            BindingList<PKModel> bd = new BindingList<PKModel>();
            dgvPKinfo.DataSource = bd;
            foreach (PKModel P in pklist)
            {
                bd.Add(P);
            }
        }
        private void dgvLockInfoRef()
        {
            BindingList<LockModel> bd = new BindingList<LockModel>();
            dgvLockInfo.DataSource = bd;
            foreach (LockModel P in lockList)
            {
                bd.Add(P);
            }
        }
        private void dgvJCRef()
        {
            BindingList<CJModel_Show> bd = new BindingList<CJModel_Show>();
            dgvJC.DataSource = bd;
            foreach (CJModel_Show P in cjShowlist)
            {
                bd.Add(P);
            }
        }
        /// <summary>
        /// 将异步执行的操作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            int port = int.Parse(e.Argument.ToString());

            int js = 0;
            //创建服务器监听
            TcpListener server = new TcpListener(IPAddress.Any, port);
            //最大可支持10个挂起的连接
            server.Start(10);
            while (true)
            {
                try
                {
                    
                    //接收连接请求
                    if (backgroundWorker1.CancellationPending)
                    {
                        e.Cancel = true;
                        Common.WriteLog("用户取消了监听");
                        server.Stop();
                        return;
                    }
                    TcpClient client = server.AcceptTcpClient();
                    client.ReceiveTimeout = 10 * 1000;//10秒无数据则停止等待
                    NetworkStream stream = client.GetStream();

                    #region 已连接
                    byte[] buffer = new byte[4096];
                    while (true)
                    {
                        try
                        {
                            if (backgroundWorker1.CancellationPending)
                            {
                                e.Cancel = true;
                                Common.WriteLog("用户取消了监听");
                                stream.Close();
                                client.Client.Shutdown(SocketShutdown.Both);
                                client.Client.Close();
                                client.Close();
                                server.Stop();
                                return;
                            }

                            if (!client.Connected)//客户端断开后退出当前循环
                                break;
                            js++;
                            //从流数据里面获取数据
                            int lenth = stream.Read(buffer, 0, buffer.Length);

                            if (lenth > 0)
                            {
                                #region 接收
                                if (lenth <= 32)
                                {
                                    Common.WriteLog("非法指令:" + BitConverter.ToString(buffer, 0, lenth));
                                    continue;
                                }

                                //处理流数据
                                Common.WriteLog("未解密设备请求:" + BitConverter.ToString(buffer, 0, lenth));

                                string msg;
                                string retheadstr = "";
                                if (true)
                                {
                                    //取出未加密的头部
                                    byte[] rethead = new byte[32];
                                    for (int i = 0; i < 32; i++)
                                    {
                                        rethead[i] = buffer[i];
                                    }

                                    retheadstr = Encoding.UTF8.GetString(rethead);
                                    int len1 = Convert.ToInt32(retheadstr.Substring(0, 6));

                                    //根据长度取出后续报文,不是16的倍数时需要同时取出补充的空格
                                    int bc = 0;
                                    if ((len1 - 32) % 16 != 0)
                                    {
                                        bc = 16 - ((len1 - 32) % 16);
                                    }

                                    byte[] retbody = new byte[len1 - 32 + bc];
                                    for (int i = 0; i < retbody.Length; i++)
                                    {
                                        retbody[i] = buffer[i + 32];
                                    }
                                    //解密
                                    msg = Common.Decrypt(retbody, AseKey).Trim();

                                    if (cbOpenReport.Checked)
                                    {
                                        Common.WriteLog("解密设备请求:" + retheadstr + msg);
                                        Reports.Add(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "-->设备请求:" + retheadstr + msg);
                                        if (Reports.Count > 10)
                                        {
                                            Reports.RemoveRange(0, Reports.Count - 10);
                                        }
                                    }
                                }
                                else
                                {
                                    msg = Encoding.UTF8.GetString(buffer, 0, lenth);
                                    retheadstr = msg.Substring(0, 32);
                                    msg = msg.Substring(32);

                                    //修改List 试试
                                    if (pklist == null)
                                        pklist = new List<PKModel>();
                                    pklist.Add(new PKModel()
                                    {
                                        Ex_BoxId = js + "",
                                        Ex_BoxPower = "test" + js,
                                        Ex_PartId = "test" + js,
                                        Ex_PartStatus = "开启" + js
                                    });

                                }
                                XmlDocument doc = new XmlDocument();
                                doc.LoadXml(msg);
                                string xml = string.Empty;
                                switch (retheadstr.Substring(6, 4))
                                {
                                    case "2005": xml = PKResult(doc); break;
                                    case "3001": xml = Report3001(doc); break;
                                    case "3002": xml = Report3002(doc); break;
                                    case "4001": xml = Report4001(doc); break;
                                    default: Common.WriteLog("命令不存在:" + msg.Substring(6, 4)); break;
                                }
                                #endregion

                                #region 回复
                                //回复的头部信息用原来的
                                string head = retheadstr.Substring(6);
                                if (cbOpenReport.Checked)
                                {
                                    Common.WriteLog("加密前服务器应答:" + ((head + xml).Length + 6).ToString().PadLeft(6, '0') + head + xml);
                                    Reports.Add(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "-->服务器应答:" + ((head + xml).Length + 6).ToString().PadLeft(6, '0') + head + xml);
                                    if (Reports.Count > 10)
                                    {
                                        Reports.RemoveRange(0, Reports.Count - 10);
                                    }
                                }

                                //需要加密
                                byte[] newXml = Common.Encrypt(xml, AseKey);

                                byte[] newbyte = new byte[newXml.Length + 32];
                                byte[] headbyte = System.Text.Encoding.Default.GetBytes(head);
                                byte[] len = System.Text.Encoding.Default.GetBytes((newXml.Length + 32).ToString().PadLeft(6, '0'));

                                for (int i = 0; i < newbyte.Length; )
                                {
                                    if (i < 6)
                                    {
                                        //前6位长度
                                        for (int j = 0; j < len.Length; j++)
                                        {
                                            newbyte[i++] = len[j];

                                        }
                                    }
                                    if (i < 32 && i >= 6)
                                    {
                                        //剩下的报文头
                                        for (int j = 0; j < headbyte.Length; j++)
                                        {
                                            newbyte[i++] = headbyte[j];
                                        }
                                    }
                                    if (i >= 32)
                                    {
                                        //报文体
                                        for (int j = 0; j < newXml.Length; j++)
                                        {
                                            newbyte[i++] = newXml[j];
                                        }
                                    }
                                }

                                Common.WriteLog("加密后服务器应答:" + BitConverter.ToString(newbyte));

                                stream.Write(newbyte, 0, newbyte.Length);
                                stream.Flush();
                                #endregion

                                backgroundWorker1.ReportProgress(js);
                            }
                            else
                            {
                                break;
                            } 
                        }
                        catch (SocketException)
                        {

                            try
                            {
                                Common.WriteLog("出现Socket异常,连接已断开");
                                client.Client.Shutdown(SocketShutdown.Both);
                                client.Client.Close();
                                client.Close();
                            }
                            catch { }
                            break;
                        }
                        catch (Exception ex)
                        {
                            Common.WriteLog("处理监听数据异常,异常信息:" + ex.Message + ";详细信息:" + ex.StackTrace);

                            stream.Close();
                            client.Close();
                            server.Stop();
                            break;
                        }

                    }
                    #endregion
                }
                catch(Exception ex)
                {
                    Common.WriteLog("监听器出现异常,异常信息:" + ex.Message + ";详细信息:" + ex.StackTrace);
                    break;
                }
            }
        }
        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            //完成,此判断是取消的,还是自然完成的
            if (e.Cancelled)
                MessageBox.Show("监听已终止");
            else
                MessageBox.Show("监听意外停止,请打开查看日志查看详情");
            if (e.Error != null)
                MessageBox.Show("监听异常停止,异常信息:" + e.Error.Message);

            tbServerPort.Enabled = true;
            label16.Text = "监听停止";
            label16.ForeColor = Color.Red;
            backgroundWorker1.Dispose();
        }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值