zoukankan      html  css  js  c++  java
  • 康耐德C2000开关量采集

         康耐德C2000设备可配置作为客户端和服务端两种方式,本次介绍的是将其作为服务端(采用服务端的好处是采集器开关量主动推送给已建立连接的客户端,客户端只需建立一个长连接,实时监测服务端是否发送开关量数据过来)进行通信,通信方式采用TCP/IP协议,通过康耐德官方的【C2000设备管理监控工作站】进行设备的IP,port等配置即可建立通信。

    客户端与服务端(C2000)通信的相关主要代码附上

    1. 因为是多台设备所以采用多线程分开运作,互不干涉
      private void OpenC2000Connect()
              {
                  try
                  {
                      ThreadForC2000_topStitchLine = new Thread(C2000DriveFor_topStitchLine);
                      ThreadForC2000_topStitchLine.IsBackground = true;
                      ThreadForC2000_getOffLine = new Thread(C2000DriveFor_getOffLine);
                      ThreadForC2000_getOffLine.IsBackground = true;
                      ThreadForC2000_assemblyLine = new Thread(C2000DriveFor_assemblyLine);
                      ThreadForC2000_assemblyLine.IsBackground = true;
                      ThreadForC2000_topStitchLine.Start();
                      ThreadForC2000_getOffLine.Start();
                      ThreadForC2000_assemblyLine.Start();
                  }
                  catch
                  {
                      throw;
                  }
              }
    2. 初始化Socket链接
       private void Initialize_topStitchLineC2000()
              {
                  try
                  {
                      IPAddress ip = IPAddress.Parse(C2000_topStitchLineIP);
                      var ipe = new IPEndPoint(ip, port);
                      SocketFor_topStitchLine.Connect(ipe);
                      SocketFor_topStitchLine.BeginReceive(RecieveFor_topStitchLine, 0, RecieveFor_topStitchLine.Length, SocketFlags.None, new AsyncCallback(ReceiveCallBack_topStitchLine), null);
                  }
                  catch
                  {
                      throw;
                  }
              }
        private void Initialize_getOffLineC2000()
              {
                  try
                  {
                      IPAddress ip = IPAddress.Parse(C2000_getOffLineIP);
                      var ipe = new IPEndPoint(ip, port);
                      SocketFor_getOffLine.Connect(ipe);
                      SocketFor_getOffLine.BeginReceive(RecieveFor_getOffLine, 0, RecieveFor_getOffLine.Length, SocketFlags.None, new AsyncCallback(ReceiveCallBack_getOffLine), null);
                  }
                  catch
                  {
                      throw;
                  }
              }
        private void Initialize_assemblyLineC2000()
              {
                  try
                  {
                      IPAddress ip = IPAddress.Parse(C2000_assemblyLineIP);
                      var ipe = new IPEndPoint(ip, port);
                      SocketFor_assemblyLine.Connect(ipe);
                      SocketFor_assemblyLine.BeginReceive(RecieveFor_assemblyLine, 0, RecieveFor_assemblyLine.Length, SocketFlags.None, new AsyncCallback(ReceiveCallBack_assemblyLine), null);
                  }
                  catch
                  {
                      throw;
                  }
              }
    3. 异步监视服务端返回值
       private void ReceiveCallBack_topStitchLine(IAsyncResult IAR)
              {
                  try
                  {
                      int REnd = SocketFor_topStitchLine.EndReceive(IAR);
                      var cmd = RecieveFor_topStitchLine.ConvertToHexStringFromHexByte(REnd);
                      var state = BLL.Common.Setting.RunningState.runing;
                      if (cmd == DataSetCache.C2000_CMD.D1_runing ||
                          cmd == DataSetCache.C2000_CMD.D1D2D2_runing)
                          state = BLL.Common.Setting.RunningState.runing;
      
                      if (cmd == DataSetCache.C2000_CMD.D1D2 ||
                          cmd == DataSetCache.C2000_CMD.D1D2D1 ||
                          cmd == DataSetCache.C2000_CMD.D2)
                          state = BLL.Common.Setting.RunningState.fault;
      
                      if (cmd == DataSetCache.C2000_CMD.D1Off)
                          state = BLL.Common.Setting.RunningState.stop;
      
                      DataSetCache.Services.TopStitchInsert(state);
                      SocketFor_topStitchLine.BeginReceive(RecieveFor_topStitchLine, 0, RecieveFor_topStitchLine.Length, 0, new AsyncCallback(ReceiveCallBack_topStitchLine), null);
                  }
                  catch (Exception ex)
                  {
                      Logger.Error(ex.Message);
                  }
              }
      private void ReceiveCallBack_getOffLine(IAsyncResult IAR)
              {
                  try
                  {
                      int REnd = SocketFor_getOffLine.EndReceive(IAR);
                      var cmd = RecieveFor_getOffLine.ConvertToHexStringFromHexByte(REnd);
      
                      var state = BLL.Common.Setting.RunningState.runing;
                      if (cmd == DataSetCache.C2000_CMD.D1_runing ||
                          cmd == DataSetCache.C2000_CMD.D1D2D2_runing)
                          state = BLL.Common.Setting.RunningState.runing;
      
                      if (cmd == DataSetCache.C2000_CMD.D1D2 ||
                          cmd == DataSetCache.C2000_CMD.D1D2D1 ||
                          cmd == DataSetCache.C2000_CMD.D2)
                          state = BLL.Common.Setting.RunningState.fault;
      
                      if (cmd == DataSetCache.C2000_CMD.D1Off)
                          state = BLL.Common.Setting.RunningState.stop;
      
                      DataSetCache.Services.GetOffLineInsert(state);
      
                      SocketFor_getOffLine.BeginReceive(RecieveFor_getOffLine, 0, RecieveFor_getOffLine.Length, 0, new AsyncCallback(ReceiveCallBack_getOffLine), null);
                  }
                  catch (Exception ex)
                  {
                      Logger.Error(ex.Message);
                  }
              }
      private void ReceiveCallBack_assemblyLine(IAsyncResult IAR)
              {
                  try
                  {
                      int REnd = SocketFor_assemblyLine.EndReceive(IAR);
                      var cmd = RecieveFor_assemblyLine.ConvertToHexStringFromHexByte(REnd);
      
                      var state = BLL.Common.Setting.RunningState.runing;
                      if (cmd == DataSetCache.C2000_CMD.D1_runing ||
                          cmd == DataSetCache.C2000_CMD.D1D2D2_runing)
                          state = BLL.Common.Setting.RunningState.runing;
      
                      if (cmd == DataSetCache.C2000_CMD.D1D2 ||
                          cmd == DataSetCache.C2000_CMD.D1D2D1 ||
                          cmd == DataSetCache.C2000_CMD.D2)
                          state = BLL.Common.Setting.RunningState.fault;
      
                      if (cmd == DataSetCache.C2000_CMD.D1Off)
                          state = BLL.Common.Setting.RunningState.stop;
      
                      DataSetCache.Services.AssemblyLineInsert(state);
      
                      SocketFor_assemblyLine.BeginReceive(RecieveFor_assemblyLine, 0, RecieveFor_assemblyLine.Length, 0, new AsyncCallback(ReceiveCallBack_assemblyLine), null);
                  }
                  catch (Exception ex)
                  {
                      Logger.Error(ex.Message);
                  }
              }

    在开发客户端通信的过程中碰到几点问题,在这里把遇到的问题以及解决方案介绍下:

    1. 因客户端安装在服务器上,设备安装在现场,现场下班就会断电,服务器是不会关机的,这就导致当现场断电采集器(服务端),第二天开机是,和客户端已经建立的连接客户端还记得,但是服务端已经不记得啦。客户端这个时候就很尴尬,连接不上服务端, 重连又告诉你,你已经有连接啦。怎么办?

    解:

     public void C2000Drive()
            {
                while (true)
                {
                    try
                    {
                        if (C2000IP.PingIp())
                        {
                            if (!SocketForLine.Connected)
                                InitializeLineC2000();
                            timerC2000Line();
                        }
                        else
                        {
                            if (SocketForLine.Connected)
                            {
                                SocketForLine.Close();
                                SocketForLine = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                            } lbl_C2000Line.Image = Resources.black;
                        } Thread.Sleep(5000);
                    }
                    catch (Exception ex)
                    {
                        Logger.Error(ex.Message);
                    }
                }
            }

    当服务端IP地址ping不同的时候,并且Socket连接仍然是Connected状态(不主动关闭,即使服务端断了,连接状态还是Connected,我擦,网都不通啦,还连接个啥啊)的情况下,手动关闭连接并重新实例化Socket对象(以备等明天上班再送电重连)。

  • 相关阅读:
    HTML 基本知识
    Vue.js 基本内容
    机器学习概述
    9 验证回文串
    c 字符串的一些常用函数
    8 有效的字母异位词
    7 字符串中的第一个唯一字符
    对公平锁、非公平锁、可重入锁、递归锁、自旋锁的理解
    一个解释volatile关键字最好的例子
    Singleton多种实现方式的在多线程情况下的优缺点
  • 原文地址:https://www.cnblogs.com/mr-meng/p/5826496.html
Copyright © 2011-2022 走看看