激光打标机TCP Socket通信协议:KZ指令集实战

激光打标机TCP Socket通信协议:KZ指令集实战

一、引言

定位到打标区域后,上位机需要控制激光打标机执行打标。本项目通过TCP Socket 与打标机软件通信,使用一套自定义的KZ指令集 。本文从第一性原理出发,讲解TCP通信的本质,并结合项目中的Laser.cs代码,深入剖析Socket连接、指令收发、协议握手、打标流程等关键技术。

二、第一性原理:TCP通信的本质

2.1 什么是TCP

TCP(Transmission Control Protocol)是互联网的基础传输协议,提供可靠的、面向连接的字节流传输。与UDP不同,TCP保证数据按序到达、不丢失、不重复。

2.2 客户端/服务器模型

TCP通信采用客户端/服务器(C/S)模型

  • 服务器(Server):监听端口,等待连接。
  • 客户端(Client):主动连接服务器。

本项目上位机是客户端 ,打标机软件是服务器。上位机主动连接打标机的IP和端口。

2.3 长连接与短连接

TCP连接有两种模式:

  • 短连接:每次通信都建立连接,用后即断。
  • 长连接:建立一次连接,多次通信,用后关闭。

本项目使用长连接,因为打标流程包含多个步骤(连接、加载模板、设置内容、执行、关闭),需要保持连接状态。

三、项目中的TCP通信

3.1 连接参数

Laser.cs中,定义了服务器地址和端口:

csharp 复制代码
private const string serverIP = "192.168.30.31";  // 打标机IP
private const int port = 6060;                    // 打标机端口

3.2 创建TCP连接

CreateTcp方法建立TCP连接:

csharp 复制代码
private bool CreateTcp()
{
    try
    {
        client = new TcpClient(serverIP, port);  // 长连接
        Thread.Sleep(100);
        stream = client.GetStream();  // 获取网络流
        string response = ReceiveResponse();
        response = response.Replace("\r\n", "");  // 去掉换行
        if (response == "OK")
        {
            return true;
        }
        else
        {
            Console.WriteLine("创建Tcp失败");
            return false;
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine("创建Tcp失败:" + ex.Message);
        return false;
    }
}

关键点:

  1. new TcpClient(serverIP, port):创建TCP客户端并连接服务器。
  2. client.GetStream():获取网络流,用于读写数据。
  3. Thread.Sleep(100):等待服务器响应。
  4. 握手验证:连接后接收服务器返回的"OK",验证连接成功。

3.3 发送指令

SendCommand方法发送指令:

csharp 复制代码
private void SendCommand(string command)
{
    if (stream != null && stream.CanWrite)
    {
        byte[] data = Encoding.ASCII.GetBytes(command);
        stream.Write(data, 0, data.Length);
    }
}

指令以ASCII编码发送,以\r\n结尾(如"KZOpenRequest\r\n")。

3.4 接收响应

ReceiveResponse方法接收响应:

csharp 复制代码
private string ReceiveResponse()
{
    if (stream != null && stream.CanRead)
    {
        try
        {
            byte[] data = new byte[1024];
            int bytes = stream.Read(data, 0, data.Length);
            Console.WriteLine("Received bytes: " + bytes);
            if (bytes > 0)
            {
                Console.WriteLine("Raw data: " + BitConverter.ToString(data, 0, bytes));
                string response = Encoding.UTF8.GetString(data, 0, bytes);
                return response;
            }
            else
            {
                MessageBox.Show("No data received from server.");
                return null;
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error receiving response: " + ex.Message);
            return null;
        }
    }
    return null;
}

四、KZ指令集详解

4.1 指令集概览

项目使用的KZ指令集包括:

指令 方向 说明
KZOpenRequest 上位机→打标机 请求打开
KZOpenOk 打标机→上位机 打开成功
KZSetFile: 路径 上位机→打标机 加载模板文件
KZSetFile 打标机→上位机 模板加载成功
KZSetContent: TEXT1,内容 上位机→打标机 设置打标内容
KZSetContentOK 打标机→上位机 内容设置成功
KZRequest 上位机→打标机 请求执行打标
KZFinished 打标机→上位机 打标完成
KZCloseRequest 上位机→打标机 请求关闭
KZCloseOK 打标机→上位机 关闭成功

4.2 指令格式

指令采用文本协议,格式为:

复制代码
指令名[: 参数]\r\n
  • 指令名:如KZOpenRequest
  • 参数:可选,用冒号分隔,如KZSetFile: D:\template.txt
  • 结尾:\r\n(回车换行)。

4.3 响应匹配

上位机发送指令后,接收响应并匹配:

csharp 复制代码
private bool ConnectTcp()
{
    try
    {
        SendCommand("KZOpenRequest\r\n");  // 发送打开请求
        Thread.Sleep(100);
        string response = ReceiveResponse();
        response = response.Replace("\r\n", "");  // 去掉换行
        if (response == "KZOpenOk")  // 匹配响应
        {
            return true;
        }
        else
        {
            Console.WriteLine("连接失败");
            return false;
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine("连接失败:" + ex.Message);
        return false;
    }
}

五、完整打标流程

5.1 Run方法

Run方法编排了完整的打标流程:

csharp 复制代码
public void Run()
{
    bool ret;
    ret = CreateTcp();   // 1. 创建TCP连接
    if (!ret) { return; }
    ret = ConnectTcp();  // 2. 打开连接
    if (!ret) { stream.Close(); client.Close(); return; }
    ret = LoadTemplate();  // 3. 加载模板
    if (!ret) { stream.Close(); client.Close(); return; }
    ret = LoadContent();   // 4. 设置内容
    if (!ret) { stream.Close(); client.Close(); return; }
    ret = Engrave();       // 5. 执行打标
    if (!ret) { stream.Close(); client.Close(); return; }
    ret = CloseTcp();      // 6. 关闭连接
    if (!ret) { stream.Close(); client.Close(); return; }
    stream.Close();
    client.Close();
}

5.2 流程状态机

这个流程是一个顺序状态机

复制代码
创建连接 → 打开 → 加载模板 → 设置内容 → 执行打标 → 关闭

每一步都检查返回值,失败则中断并关闭连接。这种"顺序执行、失败即停"的模式,保证了打标流程的可靠性。

5.3 加载模板

LoadTemplate方法加载打标模板:

csharp 复制代码
private bool LoadTemplate()
{
    try
    {
        SendCommand("KZSetFile: " + CConfig.TemplatePath + "\r\n");  // 发送模板路径
        Thread.Sleep(100);
        string response = ReceiveResponse();
        if (response == "KZSetFile")  // 匹配响应
        {
            return true;
        }
        else
        {
            Console.WriteLine("加载模板失败");
            return false;
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine("加载模板失败:" + ex.Message);
        return false;
    }
}

模板路径从配置中读取(CConfig.TemplatePath),通过KZSetFile指令发送给打标机。

5.4 设置内容

LoadContent方法设置打标内容:

csharp 复制代码
private bool LoadContent()
{
    try
    {
        SendCommand("KZSetContent: TEXT1,公司名称\r\n");  // 设置内容
        Thread.Sleep(100);
        string response = ReceiveResponse();
        if (response == "KZSetContentOK")
        {
            return true;
        }
        else
        {
            Console.WriteLine("设置内容失败");
            return false;
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine("设置内容失败:" + ex.Message);
        return false;
    }
}

KZSetContent: TEXT1,公司名称表示在TEXT1文本框中设置内容为"公司名称"。

5.5 执行打标

Engrave方法执行打标:

csharp 复制代码
private bool Engrave()
{
    try
    {
        SendCommand("KZRequest\r\n");  // 请求打标
        Thread.Sleep(1000);  // 等待打标完成
        string response = ReceiveResponse();
        if (response == "KZFinished")  // 打标完成
        {
            return true;
        }
        else
        {
            Console.WriteLine("打标失败");
            return false;
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine("打标失败:" + ex.Message);
        return false;
    }
}

打标是耗时操作,Thread.Sleep(1000)等待1秒后接收"KZFinished"响应。

六、打标控制界面

6.1 LaserLettering窗体

项目还提供了一个独立的打标控制界面LaserLettering.cs,允许用户手动控制打标流程:

csharp 复制代码
private void SetConnect_Click(object sender, EventArgs e)
{
    client = new TcpClient(serverIP, port);  // 连接
    Thread.Sleep(1000);
    stream = client.GetStream();
    string response = ReceiveResponse();
    response = response.Replace("\r\n", "");
    if (response == "OK") { }
    else { MessageBox.Show("Failed to connect to server."); }
}

这个界面提供了连接、打开、设置内容、执行、关闭等按钮,方便调试和手动操作。

6.2 手动控制按钮

LaserLettering界面包含多个控制按钮:

  • SetConnect:连接服务器。
  • ConformConnect:确认连接(发送KZOpenRequest)。
  • SetContent:设置内容。
  • ExecuteEngrave:执行打标。
  • CloseEquipment:关闭设备。
  • Run:一键执行完整流程。

七、TCP通信的工程要点

7.1 可靠性设计

  1. 握手验证:连接后验证"OK"响应,确保连接成功。
  2. 响应匹配:每条指令都匹配预期响应,失败即中断。
  3. 异常处理:用try/catch捕获通信异常。

7.2 时序控制

  1. Thread.Sleep:指令间用Sleep等待响应,避免发送过快。
  2. 超时:打标等耗时操作需要足够长的等待时间。

7.3 协议设计建议

  1. 指令规范化:指令名、参数格式统一。
  2. 响应明确:每个指令有明确的成功/失败响应。
  3. 版本管理:协议变更时做好版本兼容。

八、总结

本文从第一性原理出发,讲解了激光打标机TCP Socket通信协议:

  1. TCP通信本质:可靠的字节流传输,C/S模型。
  2. 长连接:一次连接多次通信。
  3. KZ指令集:文本协议,指令+参数+换行。
  4. 打标流程:创建→打开→加载模板→设置内容→执行→关闭。
  5. 状态机:顺序执行、失败即停。

TCP通信是上位机控制外部设备的重要手段。下一篇文章将深入讲解INI配置文件读写技术。

相关推荐
Zguigo1 小时前
lesson30-32计算机网络第四章:网络层核心三课(作用、IP协议、IPv4地址)
tcp/ip·计算机网络·php
2401_894915536 小时前
Geo 优化源码部署实战:环境配置、参数调优完整指南
运维·服务器·数据库·tcp/ip·安全
Doraemomo8 小时前
Linux编程-socket网络编程之TCP
linux·网络·tcp/ip
Loongproxy10 小时前
2026年动态IP代理真实可用率怎么横评?爬虫选代理的关键是什么
服务器·网络·网络协议·tcp/ip
Mortalbreeze10 小时前
深入理解 TCP 协议(二):TCP 可靠传输与高效通信机制详解
linux·服务器·网络·网络协议·tcp/ip
bksczm10 小时前
细谈传输层TCP协议API接口的底层原理
服务器·网络·tcp/ip
我爱cope1 天前
【计算机网络 | 网络层1:网络层的职责:IP 协议究竟解决了什么问题?】
网络·tcp/ip·计算机网络
tang777891 天前
Scrapy框架动态IP自动轮换集成配置教程
爬虫·tcp/ip·scrapy·架构·爬虫代理·动态ip
牛大兵1 天前
机顶盒获取局域网已经使用IP,开放的端口号,扫描摄像头,NAS,共享主机等开机自启局域网全量扫描工具
数据库·网络协议·tcp/ip