编写VisionPro作业脚本实现TCP服务器的监听

上一节中已经在脚本中添加了代码,实际操作这篇内容,那需要完成上一篇的内容:编写二维码识别Quickbuild工程本文在作业配置中添加代码,完整代码如下:

using System;
using System.Net;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using System.Windows.Forms;
using System.Collections.Generic;
using Cognex.VisionPro;
using Cognex.VisionPro.QuickBuild;


public class UserScript : CogJobBaseScript
{
  //集合可以看似数组,集合的长度是可变得,其元素是object类型
  //泛型集合时指定了数据类型的集合
  private object _lock=new object();
  
  //定义NetworkStream的泛型集合
  private List<NetworkStream>_streams = new List<NetworkStream>();
  
  //定义TCPClient的泛型集合
  private List<TcpClient>_clients = new List<TcpClient>();
  
  //服务器端监听对象
  private TcpListener _listener;
  
  //连接线程
  private Thread _connectionThread;
  
  //定义Thread泛型集合
  private List<Thread> _threads=new List<Thread>();
  
  //接受数据总长度
  private long _totalBytes;
  
  //作业
  private CogJob MyJob;

#region "When an Acq Fifo Has Been Constructed and Assigned To The Job"
  // This function is called when a new fifo is assigned to the job.  This usually
  // occurs when the "Initialize Acquisition" button is pressed on the image source
  // control.  This function is where you would perform custom setup associated
  // with the fifo.
  public override void AcqFifoConstruction(Cognex.VisionPro.ICogAcqFifo fifo)
  {
  }
#endregion

#region "When an Acquisition is About To Be Started"
  // Called before an acquisition is started for manual and semi-automatic trigger
  // models.  If "Number of Software Acquisitions Pre-queued" is set to 1 in the
  // job configuration, then no acquisitions should be in progress when this
  // function is called.
  public override void PreAcquisition()
  {
    // To let the execution stop in this script when a debugger is attached, uncomment the following lines.
    // #if DEBUG
    // if (System.Diagnostics.Debugger.IsAttached) System.Diagnostics.Debugger.Break();
    // #endif

  }
#endregion

#region "When an Acquisition Has Just Completed"
  // Called immediately after an acquisition has completed.
  // Return true if the image should be inspected.
  // Return false to skip the inspection and acquire another image.
  public override bool PostAcquisitionRefInfo(ref Cognex.VisionPro.ICogImage image,
                                                  Cognex.VisionPro.ICogAcqInfo info)
  {
    // To let the execution stop in this script when a debugger is attached, uncomment the following lines.
    // #if DEBUG
    // if (System.Diagnostics.Debugger.IsAttached) System.Diagnostics.Debugger.Break();
    // #endif

    return true;
  }
#endregion

#region "When the Script is Initialized"
  //Perform any initialization required by your script here.
  public override void Initialize(CogJob jobParam)
  {
    //DO NOT REMOVE - Call the base class implementation first - DO NOT REMOVE
    base.Initialize(jobParam);
    
    //将当前作业可以复制给Myjob
    MyJob = jobParam;
    
    //开启线程
    StartThreading();
  }
#endregion
  
  //开启线程实现服务器的端口监听
  private void StartThreading()
  {
    try 
    {
      _totalBytes = 0;
      
      //_connectionThread对象实例化
      _connectionThread = new System.Threading.Thread(new ThreadStart(ConnectToClient));
      
      //线程后台运行
      _connectionThread.IsBackground = true;
      
      //线程开始运行
      _connectionThread.Start();
    }
    catch(Exception ex)
    {
      MessageBox.Show("线程启动失败");
    }
  }
  
  //连接到客户端
  private void ConnectToClient()
  {
    try
    {
      //开始监听6001端口
      _listener = new TcpListener(IPAddress.Any, 6001);
      
      _listener.Start();
    }
    catch(SocketException se)
    {
      MessageBox.Show("服务器监听失败" + se.Message);
      
      StopServer();
      
      return;
    }
    
    //监听客户端的连接请求
    try
    {
      for(;;)
      {
        //等待客户端的连接请求
        TcpClient client = _listener.AcceptTcpClient();
        
        //创建线程开始接受客户端数据
        Thread t = new Thread(new ParameterizedThreadStart(ReceiveDataFromClient));
        
        //线程后台运行
        t.IsBackground = true;
        
        //线程优先级
        t.Priority = ThreadPriority.AboveNormal;
        
        //线程名称
        t.Name = "Handle Client";
        
        //开启线程
        t.Start(client);
        
        //将线程对象添加到泛型集合里
        _threads.Add(t);
        
        //将客户端添加到泛型集合里
        _clients.Add(client);
      }
    }
    catch(SocketException ex)
    {
      MessageBox.Show("Socket错误" + ex.Message);
    }
    catch(Exception ex)
    {
      MessageBox.Show("异常错误" + ex.Message);
    }
  }
  
  //接受客户端传过来的数据
  public void ReceiveDataFromClient(object clientObject)
  {
    //定义TcpClient对象并赋值
    TcpClient client = clientObject as TcpClient;
    
    //定义NetworkStream对象并赋值
    NetworkStream netStream = null;
    
    try
    {
      //获取客户端的网络数据流
      netStream = client.GetStream();
    }
    catch(Exception ex)
    {
      if(netStream != null) netStream.Close();
      MessageBox.Show("异常错误" + ex.Message);
      return;
    }
    
    if(netStream.CanRead)
    {
      //将数据流添加到_streams泛型集合里
      _streams.Add(netStream);
      try
      {
        byte[] receiveBuffer = new byte[512];
        int bytesReceived;
        
        //循环读取客户端发来的数据
        while((bytesReceived = netStream.Read(receiveBuffer, 0, receiveBuffer.Length)) > 0)
        {
          if(Encoding.ASCII.GetString(receiveBuffer, 0, bytesReceived) == "s")
          {
            MyJob.RunContinuous();
            //MessageBox.Show("接受到的数据:"+Encoding.ASCII.GetString(receiveBuffer,0,bytesReceived);
          }
          
          if(Encoding.ASCII.GetString(receiveBuffer, 0, bytesReceived) == "e")
          {
            MyJob.Stop();
            //MessageBox.Show("接受到的数据:"+Encoding.ASCII.GetString(receiveBuffer, 0, bytesReceived));
          }
        }
      }
      catch(Exception ex)
      {
        MessageBox.Show("异常错误" + ex.Message);
      }
    }
  }
  
  //停止服务器
  private void StopServer()
  {
    if(_listener != null)
    {
      //关闭TCP监听
      _listener.Stop();
      
      //等待服务器线程中断
      _connectionThread.Join();
      
      //关闭所有客户端的网络数据流
      foreach(NetworkStream s in _streams)
        s.Close();
      
      //清除_streams泛型集合里的内容
      _streams.Clear();
      
      //关闭客户端连接
      foreach(TcpClient client in _clients)
        client.Close();
      
      //清除_clients泛型集合里的内容
      _clients.Clear();
      
      //等待所有客户端线程中断
      foreach(Thread t in _threads)
        t.Join();
      
      //清除_threads泛型集合里的内容
      _threads.Clear();
    
    }
  }

}

需要一个超级终端:HyperTrm,这个百度上能够下载,毕竟是购买的课程,虽然不贵,但是分享出来感觉有点不妥,所以还是不分享终端及如何连接喽。见谅。

效果:在超级终端界面输入"s"后弹出的效果如下:

参考:

蔚来教育企业店