news 2026/4/20 17:10:36

CVI基于TCP的C/S例程学习心得

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CVI基于TCP的C/S例程学习心得

欲看图文版,请PC浏览器下载附件pdf。

我想实现两个exe之间的信息互通,豆包说用TCP,遂开始学习CVI2010 TCP的例程。
遗憾的是,CVI例程向来缺乏参考文档,于是用户极不容易入门原厂例程。尤其是TCP这样的例程,本来就牵涉了一个晦涩的网路通信协议,理解例程就需要同时开两个或两个以上的project,作为主从机对着干才有实效。我于是瞎蒙了两天,终于try出来一些名堂,并写成文档,供后来者快速理解。

一、 学习TCP/IP例程Message.cws
1, 找到CVI2010的TCP/IP例程Message.cws入口
该例程Message.cws在我笔记本上的完整路径名是C:\Users\Public\Documents\National Instruments\CVI2010\samples\tcp\Message.cws。下面是通过CVI的起始页面,搜索原厂例程的步骤。

2, CVI打开Message.cws
可见一个cws里面,包含了两个project,分别是Message,和MessageReader。由于Message是加粗了的,所以是当前激活的project,在CVI中直接运行的将是MessageWriter.c对应的exe。

这里我们还需要运行MessageReader.c对应的exe,就必须再运行一个CVI并打开Message.cws,然后鼠标右键点击MessageReader,选“Set Active Project”,之后这个MessageReader就变粗体了,成为当前project。

3, CVI运行Message.cws,从server端传数据到client端
豆包说,在该例程里,MessageReader是客户端,MessageWriter是服务器,所以两个exe的启动顺序是由讲究的,必须先运行服务器MessageWriter的exe。
如何区分哪个程序是Client,哪个程序是Server呢?豆包说应以代码里的实际函数为准:
谁调用了StartTCPServer(启动监听),谁就是服务器,就必须先启动;
谁调用了ConnectToTCPServer(发起连接),谁就是客户端,就必须后启动。
如果,我们错误地首先运行了客户端的MessageReader的exe,就会在运行到ConnectToTCPServer()函数时报错,Timeout error:

所以得老打老实地先运行服务器MessageWriter的exe,后运行客户端的MessageReader的exe,两个exe才能愉快地玩耍:

您观察得很敏锐!两个GUI背后的CMD黑窗,应该跟CVI的exe没有直接关系。但是为什么我会一起截屏呢?这是因为,我最开运行客户端的MessageWriter的exe,其界面上“Send Date”按键是失活的,不晓得为啥,例程源码中也没有说明,甚至没有提及应该首先运行哪个exe呢。不由得感慨——很多时候,一个工程师如果没有第三方的支援,就会卡死在万里长征的第一步。

还好有诲人不倦的豆包啊,豆包说有可能是其他进程已经率先占用了端口号10000,导致同样使用端口号10000的MessageWriter无法启动TCP服务器。于是我就按照豆包说的,输入查看端口10000是否被占用的指令:netstat -ano | findstr 10000,结果如下,果然是有个进程已经占用了本机10000号端口。然后还可以根据端口号输入指令tasklist | findstr xxxxx,来反查是哪个软件进程占用的,居然是百度云盘。

豆包说,要么把这个进程用任务管理器杀掉,要么修改CVI例程的端口号,从10000改到10001。两种方案我都试过了,都OK。前面黑窗背景的图就是杀掉YunDetectService.exe之后再运行例程的结果,下图是修改CVI例程源码的端口号到10001之后再运行的查询结果:

其中,
进程 ID 4188 是MessageWriter_dbg.exe(服务器端),它已经成功监听了10001端口(LISTENING表示服务器在等待连接)。
进程 ID 8756是MessageReader_dbg.exe(客户端),用临时端口 63310。

二、 学习TCP/IP例程 server.cws和client.cws
该例程是基于 TCP/IP 协议的客户端 - 服务器(C/S)通信经典例程,核心演示了如何利用CVI的 sockutil 库实现跨进程/跨设备的网络数据交互。
该例程在我笔记本的文件路径是C:\Users\Public\Documents\National Instruments\CVI2010\samples\tcp\server.cws和client.cws。下面是通过CVI的起始页面,搜索原厂例程的步骤。

先后运行server.cws和client.cws,当用户往文本框输入一条字符串之后回车,会发送到另一侧并显示出来:

Server.c解析
注意到,开篇#include <tcpsupp.h>,这是CVI专属TCP通信支撑库(RegisterTCPServer/ServerTCPRead等核心API)。
函数RegisterTCPServer (portNum, ServerTCPCB, 0) 是注册 TCP 服务器的核心API。其中,portNum是端口号比如10000,ServerTCPCB是回调函数。该函数的作用是让程序在指定端口监听客户端连接,并绑定 “TCP事件回调函数ServerTCPCB”—— 即后续所有 TCP事件(客户端连接、数据收发、断开)都通过该回调函数来响应。
函数ServerTCPWrite (g_hconversation, transmitBuf, strlen(transmitBuf), 1000) 是向已连接的TCP客户端发送数据的核心API,专门用于服务器端向客户端写入数据流。
函数dataSize = ServerTCPRead (g_hconversation, receiveBuf, dataSize, 1000) 是服务器端读取客户端发送数据的核心 API,负责从已连接的TCP客户端接收数据流。该函数一般是放在回调函数ServerTCPCB中被TCP_DATAREADY事件触发所调用。
UnregisterTCPServer (portNum) 是注销 TCP 服务器的核心API,是 RegisterTCPServer 的 “反向操作”—— 用于停止服务器对指定端口的监听、释放底层套接字资源、注销 TCP 事件回调。

Client.c解析
函数ConnectToTCPServer (&g_hconversation, portNum, tempBuf, ClientTCPCB, NULL, 5000) 是 TCP 客户端主动连接服务器的核心API,用于客户端程序向指定 IP+port的TCP服务器发起连接请求,并绑定客户端的TCP事件回调函数ClientTCPCB。
函数dataSize = ClientTCPRead (g_hconversation, receiveBuf, dataSize, 1000) 是 TCP客户端读取服务器发送数据的核心API,负责从已建立的 TCP 连接中接收服务器下发的流数据。该函数一般是放在回调函数ClientTCPCB中被TCP_DATAREADY事件触发所调用。
函数ClientTCPWrite (g_hconversation, transmitBuf, strlen(transmitBuf), 1000) < 0 是TCP客户端向服务器发送数据的核心API,负责将客户端缓冲区的数据通过已建立的TCP连接发送给服务器。

三、 学习TCP/IP例程 MultiClientServer.cws
CVI2010的MultiClientServer.cws例程是一个典型的多客户端TCP服务器演示程序,主要功能是展示如何实现一个服务器同时与多个客户端建立TCP连接并进行通信。其中,服务器端(Server):作为TCP服务器,启动后监听指定端口(如默认的5000),支持同时接收多个客户端的连接请求,并为每个客户端创建独立的通信线程。客户端(Client):可同时启动多个实例,每个客户端通过TCP协议连接到服务器,实现与服务器的双向数据交互。
该例程特点如下:
多客户端并发连接:服务器通过线程池(Cmt函数库)管理多个客户端连接,避免单个客户端阻塞其他连接,支持同时处理多个客户端的请求。
双向数据通信:客户端可向服务器发送数据(如文本、数值等);
服务器接收后可实时响应(如返回确认信息、处理后的数据),并支持向指定客户端或所有客户端广播消息。
连接状态管理:服务器实时显示已连接的客户端信息(如客户端IP、端口、连接时间),支持主动断开某个客户端连接;客户端也能显示与服务器的连接状态。
异常处理:包含连接超时、客户端异常断开、网络错误等场景的处理逻辑,确保服务器稳定运行。
总的来说,该例程的核心价值是展示CVI中TCP多连接处理和线程并发编程的最佳实践,代码中包含了服务器监听、客户端连接、多线程数据收发、连接管理等关键逻辑,适合作为开发多客户端通信系统的参考模板。

该项目在我笔记本上的完整路径是C:\Users\Public\Documents\National Instruments\CVI2010\samples\tcp\MultiClientServer.cws。下面是通过CVI的起始页面,搜索原厂例程的步骤。

刚才试通了一主多从的TCP通信的例程,没有参考文档就纯粹靠瞎蒙了。这里需要开三个CVI,分别打开MultiClientServer.cws、和两个client.prj。

老规矩,先运行server即MultiClientServer.cws。初始界面这样的,很多控件都是失活的,等待client上线:

然后在默认的debug模式下运行第一个client.prj,显然server这边侦听到有一个client上线了,客户端名称列表框就多了一行记录,同时还会弹出一个窗口Message from Client出来:

然后手动修改成release模式运行第二个client.prj,可见server这边就一共侦听到两个client上线,客户端名称列表框就有了两行记录。同时再弹出一个窗口Message from Client。这里手动把两个client界面和两个Message from Client弹窗都摆好位置:

然后用户就可以尝试双边通信了:

所以我上午的设想的,一个Server.exe配合4个ATE.exe去控制一台4通道OpticaslSuit,应是完全可行的了?

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/19 8:41:54

Day 2:Git环境搭建全攻略:WindowsmacOSLinux三平台避坑指南

Day 2&#xff1a;Git环境搭建全攻略&#xff1a;Windows/macOS/Linux三平台避坑指南 “你是否曾经因为Git安装失败而对着电脑发呆&#xff0c;觉得自己像个’Git无能者’&#xff1f;别担心&#xff0c;今天这章就是为你量身定制的&#xff01;” &#x1f31f; 为什么环境搭建…

作者头像 李华
网站建设 2026/4/18 14:10:33

四足机器人技术路线总结教程

四足机器人技术路线总结教程1. 引言 四足机器人模仿自然界四足动物的运动方式&#xff0c;具有比轮式或履带式机器人更强的地形适应性和稳定性&#xff0c;在复杂、非结构化环境中&#xff08;如废墟、山地、室内复杂场景&#xff09;具有巨大应用潜力。近年来&#xff0c;随着…

作者头像 李华
网站建设 2026/4/17 17:34:00

人形机器人技术开发

人形机器人技术开发一、主流技术路线优劣势分析液压驱动方案优势&#xff1a;输出力矩大&#xff08;可达$3000\text{N}\cdot\text{m}$&#xff09;、动态响应快劣势&#xff1a;系统复杂度高、能耗大&#xff08;功率密度约$0.5\text{kW/kg}$&#xff09;、维护成本高代表案例…

作者头像 李华
网站建设 2026/4/18 9:43:46

Common Voice语音数据集完整使用手册:从入门到精通

Common Voice语音数据集完整使用手册&#xff1a;从入门到精通 【免费下载链接】cv-dataset Metadata and versioning details for the Common Voice dataset 项目地址: https://gitcode.com/gh_mirrors/cv/cv-dataset Common Voice是由Mozilla主导的开源语音数据项目&…

作者头像 李华
网站建设 2026/4/20 17:04:14

17、5G毫米波通信:技术、架构与性能

5G毫米波通信:技术、架构与性能 1. 引言 将第五代(5G)通信拓展到毫米波(mmWave)频段是当前行业和学术界广泛讨论的热门话题。毫米波频段范围通常为6 - 100 GHz,与国际移动电话(IMT)系统低于6 GHz的频谱频段相比,它拥有超宽的可用传输带宽。据调查,6 - 100 GHz之间有…

作者头像 李华