发送指令控制相机采集图像或读取本地文件图像并执行作业

该代码示例展示了使用C#实现一个简单的TCP服务器,监听6001端口,接收客户端发送的'start'和'stop'命令来控制作业的启动和停止。客户端是一个C#窗体应用,用于连接服务器并发送命令。该示例着重于网络通信和多线程处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文采用的是读取本地文件,因为没有相机,所以只能够这么操作,基本上类似。

作业中的代码如图:

配置中“作业属性”->“编辑脚本”->“C#脚本”。

作业脚本代码如下:

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) == "start")
          {
            MyJob.RunContinuous();
            //MessageBox.Show("接受到的数据:"+Encoding.ASCII.GetString(receiveBuffer,0,bytesReceived);
          }
          
          if(Encoding.ASCII.GetString(receiveBuffer, 0, bytesReceived) == "stop")
          {
            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();
    
    }
  }

}

C# Form界面如下:

代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace TCPClientApplicationProgram
{
    public partial class Form1 : Form
    {
        Socket clientSocket;
        Thread clientThread;

        public Form1()
        {
            InitializeComponent();

            //对跨线程的非法错误不检查
            Control.CheckForIllegalCrossThreadCalls = false;

            this.IP_textBox1.Text = "127.0.0.1";

            this.Port_textBox2.Text = "6001";
        }

        private void Send_button_Click(object sender, EventArgs e)
        {
            byte[] data = new byte[1024];

            //对输入信息进行编码并放到一个字节数组
            data = Encoding.ASCII.GetBytes(this.Content_textBox3.Text);

            //向服务器发送信息
            clientSocket.Send(data, data.Length, SocketFlags.None);
        }

        private void ConnectSever_button1_Click(object sender, EventArgs e)
        {
            if(this.IP_textBox1.Text=="")
            {
                MessageBox.Show("请输入IP!");
                return;
            }

            //开启一个子线程,连接到服务器
            clientThread = new Thread(new ThreadStart(ConnectToServer));
            clientThread.Start();
        }

        private void ConnectToServer()
        {
            byte[] data = new byte[1024];

            //网络地址和服务端口的组合称为端点,IPEndPoint类表示这个端口
            IPEndPoint ipep = new IPEndPoint(IPAddress.Parse(this.IP_textBox1.Text), int.Parse(this.Port_textBox2.Text));

            //初始化Socket
            clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            //将套接字与远程服务器地址相连
            try
            {
                //连接到服务器
                clientSocket.Connect(ipep);
            }
            catch(SocketException ex)
            {
                MessageBox.Show("connect error:" + ex.Message);
            }
        }
    }
}

运行效果:

参考:

蔚来教育企业店 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值