Bootstrap

C#网口通信和串口数据互相转发

最近闲来无事写了一个串口转网口的模拟机程序:
实现原理创建tcpserver监听端,接收客户端发送过来的信息,在通过com口转发出去。同样收到串口数据在通过服务端转发给客户端 如图
在这里插入图片描述

串口发送端代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;

namespace SerailPortReciv
{
    public partial class Form1 : Form
    {
        #region Var
        private SerialPort EntitySerial = null;
        private Thread ThreadRecive = null;
        private Queue<ReciveInfo> ReciveQueue = new Queue<ReciveInfo>();
        private byte[] ReciveBuffer = new byte[1024 * 2];
        private bool IsLoopBool = false;

        private int RecivePacketNU = 0;
        private double ReciveBytesNU = 0;
        private SynchronizationContext Context;

        private int SendPacketNu = 0;
        private Double SendBytesNu = 0;
        private byte[] SendDataBytsBuffer = null;
        private int SleepTiming = 0;
        private Thread ThreadSendData = null;
        private bool IsLoopSendData = false;
        private bool IsRealShowRecInfo = false;
        #endregion
        public Form1()
        {
            InitializeComponent();
            Context = SynchronizationContext.Current;
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            comboBoxOddEvent.SelectedIndex = 1;
        }
        private void btnOpenSerail_Click(object sender, EventArgs e)
        {
            if (btnOpenSerail.Text == "开启串口")
            {
                if (!InitSerialPort())
                {
                    MessageBox.Show("端口打开失败!" + txtCOM.Text);
                    return;
                }
                IsRealShowRecInfo = checkBoxRealShowInfo.Checked;
                btnOpenSerail.Text = "关闭串口";
            }
            else
            {
                CloseCom();
                btnOpenSerail.Text = "开启串口";
            }

        }

        private bool InitSerialPort()
        {
            Parity par = Parity.None;
            if (comboBoxOddEvent.SelectedItem != null)
            {
                switch (comboBoxOddEvent.SelectedItem.ToString().ToLower())
                {
                    case "even":
                        par = Parity.Even;
                        break;
                    case "none":
                        par = Parity.None;
                        break;
                    case "odd":
                        par = Parity.Odd;
                        break;
                    default:
                        par = Parity.None;
                        break;
                }
            }
            StopBits stopBit = StopBits.None;
            switch (txtStopBit.Text)
            {
                case "1":
                    stopBit = StopBits.One;
                    break;
                case "1.5":
                    stopBit = StopBits.OnePointFive;
                    break;
                case "2":
                    stopBit = StopBits.Two;
                    break;
                default:
                    stopBit = StopBits.None;
                    break;
            }
            try
            {
                EntitySerial = new SerialPort(txtCOM.Text.ToUpper(), int.Parse(txtBaudRate.Text), par, int.Parse(txtDataBit.Text), stopBit);
                EntitySerial.Open();
            }
            catch (Exception)
            {

                return false;
            }

            IsLoopBool = true;
            ThreadRecive = new Thread(ReciveMethod);
            ThreadRecive.IsBackground = true;
            ThreadRecive.Start();
            return true;
        }



        /// <summary>
        /// 接收数据线程
        /// </summary>
        void ReciveMethod()
        {
            while (IsLoopBool)
            {
                int recNU = EntitySerial.BytesToRead;
                if (recNU > 0)
                {
                    int reciveNu = EntitySerial.Read(ReciveBuffer, 0, recNU);
                    ReciveInfo entity = new ReciveInfo();
                    entity.Buffer = new byte[reciveNu];
                    entity.TimerString = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
                    Array.Copy(ReciveBuffer, entity.Buffer, reciveNu);
                    if (IsRealShowRecInfo)
                    {
                        ShowEntityInfo(entity);
                    }
                    else
                    {
                        ReciveQueue.Enqueue(entity);
                    }
                    RecivePacketNU++;
                    ReciveBytesNU += reciveNu;
                    Context.Post(ret => { labReciveInfo.Text = string.Format("{0}/{1}", RecivePacketNU, ReciveBytesNU); }, null);
                }
            }

        }

        /// <summary>
        /// 关闭串口
        /// </summary>
        void CloseCom()
        {
            RecivePacketNU = 0;
            ReciveBytesNU = 0;
            Context.Post(ret => { labReciveInfo.Text = "总包数/总字节数"; }, null);
            IsLoopBool = false;
            if (EntitySerial != null)
            {
                EntitySerial.Close();
            }
            EntitySerial = null;
            if (ThreadRecive != null && ThreadRecive.IsAlive)
            {
                ThreadRecive.Abort();
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            CloseCom();
            CloseSendData();
        }

        /// <summary>
        /// 显示接收到的数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnShowRecive_Click(object sender, EventArgs e)
        {

            lock (ReciveQueue)
            {
                while (ReciveQueue.Count > 0)
                {
                    ShowEntityInfo(ReciveQueue.Dequeue());
                    Thread.Sleep(10);
                }
            }
        }

        private void ShowEntityInfo(ReciveInfo recv)
        {
            Context.Post(ret =>
            {
                txtShowRecive.AppendText(string.Format("[{0}] # Recive \r\n", recv.TimerString));
                txtShowRecive.AppendText(GetBufferFormatHex(recv.Buffer) + "\r\n");
                txtShowRecive.AppendText("\r\n");
            }, null);
        }

        private string GetBufferFormatHex(byte[] bts)
        {
            StringBuilder sb = new StringBuilder();
            foreach (byte itemBt in bts)
            {
                sb.Append(itemBt.ToString("X2") + " ");
            }
            return sb.ToString();
        }

        #region  定时发送数据

        private void btnSendData_Click(object sender, EventArgs e)
        {
            if (btnSendData.Text == "发送数据")
            {
                bool retBool = int.TryParse(txtSendTiming.Text, out  this.SleepTiming);
                if (!retBool)
                {
                    MessageBox.Show("定时发送时间不合法!");
                    return;
                }
                try
                {
                    SendDataBytsBuffer = GetByteByHexString(txtSendData.Text);
                }
                catch
                {
                    MessageBox.Show("待发送数据有误!");
                    return;
                }
                if (checkBoxTimnigSend.Checked)
                {
                    IsLoopSendData = true;
                    ThreadSendData = new Thread(ProcSendData);
                    ThreadSendData.IsBackground = true;
                    ThreadSendData.Start();
                    btnSendData.Text = "停止";
                }
                else
                {
                    try
                    {
                        txtShowRecive.AppendText(string.Format("[{0}] # Send \r\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")));
                        EntitySerial.Write(SendDataBytsBuffer, 0, SendDataBytsBuffer.Length);
                        txtShowRecive.AppendText(GetBufferFormatHex(SendDataBytsBuffer) + "[OK]\r\n");
                    }
                    catch (Exception)
                    {
                        txtShowRecive.AppendText(GetBufferFormatHex(SendDataBytsBuffer) + "[Error]\r\n");
                    }
                    finally
                    {
                        txtShowRecive.AppendText("\r\n");
                    }
                }
            }
            else
            {
                CloseSendData();
                btnSendData.Text = "发送数据";
            }
        }

        /// <summary>
        /// 结束发送线程
        /// </summary>
        private void CloseSendData()
        {
            IsLoopSendData = false;
            if (ThreadSendData != null && ThreadSendData.IsAlive)
            {
                ThreadSendData.Abort();
            }
        }

        /// <summary>
        /// 定时发送数据
        /// </summary>
        void ProcSendData()
        {
            while (IsLoopSendData)
            {
                if (EntitySerial != null && EntitySerial.IsOpen)
                {
                    EntitySerial.Write(SendDataBytsBuffer, 0, SendDataBytsBuffer.Length);
                    SendBytesNu += SendDataBytsBuffer.Length;
                    SendPacketNu++;
                    Context.Post(ret => { labSendInfo.Text = SendPacketNu + "/" + SendBytesNu; }, null);
                }
                Thread.Sleep(SleepTiming);
            }
        }

        //16进制字符串得到byte[]
        private byte[] GetByteByHexString(string hexComTxt)
        {
            hexComTxt = hexComTxt.Replace(" ", "").Replace("\r\n", "").Replace("\t", "");
            byte[] bytes = new byte[hexComTxt.Length / 2];
            for (int i = 0; i < bytes.Length; i++)
            {
                bytes[i] = Convert.ToByte(hexComTxt.Substring(i * 2, 2), 16);
            }
            return bytes;
        }
        #endregion

        private void btnResate_Click(object sender, EventArgs e)
        {
            SendPacketNu = 0;
            SendBytesNu = 0;
            Context.Post(ret => { labSendInfo.Text = "总包数/总字节数"; }, null);
        }

        private void txtShowRecive_DoubleClick(object sender, EventArgs e)
        {
            ((TextBox)sender).Text = "";
        }

        private void checkBoxRealShowInfo_CheckedChanged(object sender, EventArgs e)
        {
            this.IsRealShowRecInfo = checkBoxRealShowInfo.Checked;
        }


    }

    class ReciveInfo
    {
        public byte[] Buffer { get; set; }
        public string TimerString { get; set; }
    }
}

嗯功能比较完整。有兴趣可以下载源码:https://download.csdn.net/download/weixin_43542114/12888689

;