C#上位机:TCP通讯实例

前言

本文主要是提供一个TCP通讯的Demo。有时候上位机需要通过TCP来进行文件与数据传输,相对于基础的IO与串口,TCP的传输内容可能更加复杂,本文尽量从多个角度来给出示例。
关于上位机的搭建与通讯我们已经有以下几个部分可供参考:
C#上位机:串口通讯
C#上位机:Modbus RTU通讯实例
C#上位机:Modbus TCP通讯实例
概念提要:
TCP通讯:一种字节流传输层通讯协议,流程为建立连接-传输数据-释放连接。
实现方式:Socket编程
监听IP:监听一个IP地址,当有数据传输时,进行接收,当无数据时保持对IP地址的监听状态。
模拟通讯:软件名:Hercules,提供TCP Clien与Server的测试端口。
在这里插入图片描述

数据传输

首先添加Socket

using System.Net;
using System.Net.Sockets;
using System.Threading;

然后在代码层添加监听

public partial class Form1 : Form
    {
        TcpListener listener;
        public Form1()
        {
            InitializeComponent();
        }
     }

在这里插入图片描述

然后我们以Client的形式向主站建立连接并发送数据。

/// <summary>
        /// 发送数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void send_Click(object sender, EventArgs e)
        {
            TcpClient client = new TcpClient();
            try
            {
                client.Connect(IPAddress.Parse(txtIp.Text), int.Parse(txtPort.Text));//建立连接
                NetworkStream ns = client.GetStream();
                int size = 9;
                byte[] buffer = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
                ns.Write(buffer, 0, size);           
                ns.Flush();
                ns.Close();
            }
            catch
            {
            }
        }

然后我们监听一个IP地址,等待Client向该IP发送数据

 /// <summary>
        /// 开始监听
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lisBegin_Click(object sender, EventArgs e)
        {
            try
            {
                listener = new TcpListener(IPAddress.Parse("127.0.0.1"), int.Parse("501"));
                listener.Start();
                //MessageBox.Show("开始监听");
                Thread th = new Thread(ReceiveMsg);//启用监听线程
                th.Start();
                th.IsBackground = true;
                button1.Text = "正在监听";//锁掉按键并显示状态
                button1.Enabled = false;
            }
            catch
            {
                MessageBox.Show("IP地址错误,监听失败");
            }
        }
         /// <summary>
        /// 监听线程
        /// </summary>
        public void ReceiveMsg()
        {
            while (true)
            {
                try
                {
                    int size = 0;
                    int len = 0;
                    TcpClient client = listener.AcceptTcpClient();

                    if (client.Connected)
                    {
                        MessageBox.Show("连接成功");
                    }
                    NetworkStream stream = client.GetStream();
                    if (stream != null)
                    {
                        byte[] buffer = new byte[512];
                        while ((size = stream.Read(buffer, 0, buffer.Length)) > 0)
                        {
                           
                            string s = Convert.ToString(buffer[0]);//输出第一位来检查连接
                            MessageBox.Show(s);
                            len += size;
                        }
                                 
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("异常:" + ex.Message);
                }
            }
        }

我们启动监听,并打开Hercules,用Client启动连接,并随意发送一段数据:
在这里插入图片描述
数据传输测试完成。
另:我们对一个端口监听的状态,不随Client的连接状态而发生改变,在实际上的生产中,我们的脚本或者是上位机可以保持长时间不间断的监听一个本地ip,并可以用Switch等硬件来实现一种类似数据采集卡的效果。

文件传输

我们以传输图片为例子,在这一步的操作中,我们在发送端要将一个文件整合成字节流发送,接收后我们再将字节流整合成文件。
首先提取文件:

FileStream fs = new FileStream(txtFileName.Text, FileMode.Open);

在发送过程中将文件流整合为字节流:

size = fs.Read(buffer, 0, buffer.Length);
ns.Write(buffer, 0, size);

这便完成了文件的发送。文件的接收则是,将字节流按照格式整合成一个文件:

string path1 = saveadress.Text;
string path = path1 +Id + ".JPG";
FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write);

在接收时:

byte[] buffer = new byte[512];
while ((size = stream.Read(buffer, 0, buffer.Length)) > 0)
{
         fs.Write(buffer, 0, size);
         len += size;
}

Demo设计与完整代码

我们设计一个发送与接收同端的Demo来进行测试代码的可行性,也就是自发自接。大概可如下:
在这里插入图片描述

/// <summary>
        /// 发送文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void sendPhoto_Click(object sender, EventArgs e)
        {
            string s;
            TcpClient client = new TcpClient();
            
            try
            {
                string Path= Path.Text;
                FileStream fs = new FileStream(Path, FileMode.Open);
                    try
                    {
                        client.Connect(IPAddress.Parse("127.0.0.1"), int.Parse("501"));//请自行向前端要ip
                        NetworkStream ns = client.GetStream();
                        int size = 0;//初始化读取的流量为0   
                        long len = 0;//初始化已经读取的流量   
                        while (len < fs.Length)
                        {
                            byte[] buffer = new byte[512];
                            size = fs.Read(buffer, 0, buffer.Length);
                            ns.Write(buffer, 0, size);
                            len += size;
                        }
                        fs.Flush();
                        ns.Flush();
                        fs.Close();
                        ns.Close();
                        MessageBox.Show( "文件发送成功");
                    }
                    catch
                    {
                        fs.Flush();
                        //ns.Flush();
                        fs.Close();
                    MessageBox.Show("文件发送失败");
                    Thread.Sleep(800);
                    }     
            }
            catch
            {        
                    MessageBox.Show("文件地址不正确!");
            }  
        }
/// <summary>
        /// 开始监听
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lisBegin_Click(object sender, EventArgs e)
        {
            try
            {
                listener = new TcpListener(IPAddress.Parse("127.0.0.1"), int.Parse("501"));
                listener.Start();
                //MessageBox.Show("开始监听");
                Thread th = new Thread(ReceiveMsg);
                th.Start();
                th.IsBackground = true;
                button1.Text = "正在监听";
                button1.Enabled = false;
            }
            catch
            {
                MessageBox.Show("IP地址错误,监听失败");
            }
        }
/// <summary>
/// 监听线程
/// </summary>
public void ReceiveMsg()
        {
           
            while (true)
            {
                TcpClient client = listener.AcceptTcpClient();
                NetworkStream stream = client.GetStream();
                if (client.Connected)
                {
                    MessageBox.Show("连接成功");
                }
                try
                {
                    int s = 1;
                    int size;
                    int len=0;
                    string yy = DateTime.Now.Year.ToString();   // 2023
                    string mm = DateTime.Now.Month.ToString();    // 6

                    string path1 = saveAdress.Text;
                    string path = path1 + "\\" + yy + "\\" + mm + "\\"  +"test "+".JPG";
                    string filename = path1 + "\\" + yy + "\\" + mm;
                    if (!Directory.Exists(filename))
                    {
                        Directory.CreateDirectory(filename);
                    }
                    while (File.Exists(path))//针对重复照片
                    {

                        path = path1 + "\\" + yy + "\\" + mm + "\\"  + "(" + Convert.ToString(s) + ")" + ".JPG";
                        s++;
                    }
                    FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write);

                    byte[] buffer = new byte[512];
                    while ((size = stream.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        fs.Write(buffer, 0, size);
                        len += size;
                    }
                    fs.Flush();
                    stream.Flush();
                    stream.Close();
                    client.Close();
                }
                catch (Exception ex)
                {
                    MessageBox.Show("异常:" + ex.Message);
                }
            }
        }

在这里插入图片描述
在这里插入图片描述

测试成功。

  • 6
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
矢量网络分析仪(Vector Network Analyzer,简称VNA)是一种用于测试和分析射频(RF)和微波电路的仪器。在C#语言中,可以利用VISA(Virtual Instrument Software Architecture)和NI(National Instruments)公司提供的NI-VISA和NI-488.2软件包,通过GPIB(General Purpose Interface Bus)或者LAN(Local Area Network)接口,与VNA进行通信和控制。 以下是一个简单的C#自动化开发Demo示例,用于控制矢量网络分析仪进行扫频测试: ```csharp using System; using NationalInstruments.Visa; namespace VNA_Automation { class Program { static void Main(string[] args) { // 创建visa设备对象 var resourceManager = new ResourceManager(); var visaDevice = resourceManager.Open("TCPIP::192.168.1.1::INSTR"); // 发送命令到visa设备 visaDevice.Write("*RST"); // 复位VNA visaDevice.Write(":SENSE:FREQ:STAR 1GHz"); // 设置起始频率 visaDevice.Write(":SENSE:FREQ:STOP 10GHz"); // 设置终止频率 visaDevice.Write(":SENSE:SWE:POIN 201"); // 设置扫描点数 visaDevice.Write(":SENSE:SWE:TYPE LIN"); // 设置线性扫描模式 visaDevice.Write(":CALC:PAR:DEF 'S11', 'S11'"); // 设置测试参数 visaDevice.Write(":CALC:FORM MLOG"); // 设置测试格式 // 读取测试结果 var response = visaDevice.Query(":CALC:DATA:FDAT?"); // 输出测试结果 Console.WriteLine(response); // 关闭visa设备对象 visaDevice.Dispose(); } } } ``` 在上述代码中,我们首先创建了一个visa设备对象,指定了VNA的IP地址和INSTR资源名。然后,通过visaDevice.Write()方法,向VNA发送了一系列命令,用于设置测试参数、格式等信息。最后,通过visaDevice.Query()方法,读取了测试结果,并输出到控制台中。在整个过程中,我们使用了NI-VISA和NI-488.2软件包提供的API,实现了C#与VNA之间的通信和控制。 需要注意的是,实际使用过程中,需要根据具体的VNA型号和测试需求,对代码进行相应的修改和优化。此外,还需要了解VNA的相关基础知识和操作方法,才能正确地进行自动化测试开发。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值