Bootstrap

串口转Socket

串口转Socket

using System;
using System.Net;
using System.Net.Sockets;
using System.IO.Ports;
using System.Threading;
using System.Text;
using System.IO;
using System.Windows.Forms;

namespace TCP2COM
{
    /// <summary>
    /// 数据转发代理
    /// </summary>
    /// <param name="reDatas">接受数据</param>
    /// <param name="length">数据长度</param>
    public delegate void DataArriveEventHandler( DataArraveArgs e);

    /// <summary>
    /// 通信设备连接代理
    /// </summary>
    /// <param name="status">连接状态</param>
    public delegate void ConStateEvetnHandler(bool status,string msg,CommType type);

    public enum CommType
    {
        /// <summary>
        /// 串口 通信
        /// </summary>
        COM = 0,

        /// <summary>
        /// Socket通信
        /// </summary>
        TCP = 1,

        /// <summary>
        /// 其它
        /// </summary>
        OTHER=2
    }

    public class DataArraveArgs : EventArgs
    {
        private byte[] reDatas;
        private int dataLen;
        private CommType type;


        public byte[] ReDatas
        {
            get { return reDatas; }
        }

        public int DataLen
        {
            get { return dataLen; }
        }

        public CommType Type
        {
            get { return type; }
        }

        public DataArraveArgs(ref byte[] reDatas, int dataLen,CommType type)
        {
            this.reDatas = reDatas;
            this.dataLen = dataLen;
            this.type = type;
        }
    }

    public class ConStateArgs : EventArgs
    {
        public bool status;
        public string msg;
        public CommType type;

        public ConStateArgs(bool status, string msg, CommType type)
        {
            this.status = status;

        }
    }

    public class ClientInfo
    {
        private const int BUFFERSIZE = 1024;
        private byte[] buffers = new byte[BUFFERSIZE];
        private int dataLen;

        public byte[] Buffers
        {
            get { return buffers; }
            set
            {
                buffers = value;
            }
        }

        public int DataLen
        {
            get { return dataLen; }
            set
            {
                if (dataLen!= value)
                {
                    dataLen = value;                 
                }
            }
        }
    }

    public class Commun
    {
        public event DataArriveEventHandler OnDataArrive;//声明一个EvenDataArriveHandler委托类型的事件
        public event ConStateEvetnHandler ConState;

        private int port;
        private string serverIP;

        private string comNum;
        private int baudRate;

        private Socket mainSocket;

        private SerialPort mainPort;

        private bool status = false;
        private string msg = string.Empty;
        private int waitTime=50;
        private bool uncheckPort=true,uncheckSocket =true;
        private bool comEdit;
        public bool Status
        {
            get { return status; }
        }
        private byte[] ErrorBuffers;

        public bool PortStatus
        {
            get { return mainPort.IsOpen; }
        }

        public bool UNCheckPort
        {
            set
            {
                uncheckPort = value;
            }
        }

        public bool UnCheckSocket
        {
            set { uncheckSocket = value; }
        }

        public int WaritTime
        {
            set
            {
                if (waitTime != value)
                {
                    waitTime = value;
                }
            }
        }

        public string ServerIP
        {
            get { return serverIP; }
            set
            {
                if (serverIP != value)
                {
                    serverIP = value;
                }
            }
        }

        public int Port
        {
            get { return port; }
            set
            {
                if (port != value)
                {
                    port =value;
                }
            }
        }

        public string ComNum
        {
            get { return mainPort.PortName; }
            set
            {
                if (comNum != value)
                {
                    comEdit = true;
                    comNum = value;
                }
                else
                {
                    comEdit = comEdit | false;
                }
            }
        }

        public int BaudRate
        {
            get { return mainPort.BaudRate; }
            set
            {
                if (baudRate != value)
                {
                    comEdit = true;
                    baudRate = value;
                }
                else
                {
                    comEdit = comEdit | false;
                }
            }
        }

        private ClientInfo portInfo = new ClientInfo();
        private ClientInfo socketInfo = new ClientInfo();

        public Commun()
        {
            mainPort = new SerialPort();
            mainPort.DataReceived += new SerialDataReceivedEventHandler(mainPort_DataReceived);
        }

        void mainPort_DataReceived(object sender,
            SerialDataReceivedEventArgs e)
        {
            Array.Clear(portInfo.Buffers, 0, portInfo.DataLen);
            portInfo.DataLen = 0;

            try
            {
                int dataLen = mainPort.BytesToRead;
                if (dataLen == 0)
                {
                    return;
                }

                while (dataLen > 0)
                {
                    portInfo.DataLen += mainPort.Read(portInfo.Buffers,
                        portInfo.DataLen, dataLen);

                    Thread.Sleep(waitTime);
                    dataLen = mainPort.BytesToRead;
                }

                if (CheckPack(portInfo.Buffers, portInfo.DataLen))
                {
                    byte[] buffers = new byte[portInfo.DataLen];
                    Array.Copy(portInfo.Buffers, 0, buffers, 0, portInfo.DataLen);

                    OnDataArrive(new DataArraveArgs(ref  buffers,
                        portInfo.DataLen, CommType.COM));

                    SendSocket(buffers);
                }
                else
                {
                    SendPort(ErrorBuffers);
                }
            }
            catch (Exception exp)
            {
#if DEBUG
                WriteLine(exp, "串口数据接受");
#endif
            }
        }

        public void Connection(object sender,EventArgs e)
        {
            try
            {
                if (comEdit)
                {
                    if (mainPort.IsOpen)
                    {
                        mainPort.Close();
                    }
                    mainPort.PortName = comNum;
                    mainPort.BaudRate = baudRate;
                    mainPort.Open();
                }
                else
                {
                    if (!mainPort.IsOpen)
                    {
                        mainPort.PortName = comNum;
                        mainPort.BaudRate = baudRate;
                        mainPort.Open();
                    }
                }

                status = mainPort.IsOpen;
            }
            catch (Exception exp)
            {
                status = false;
                msg = exp.Message;
#if DEBUG
                WriteLine(exp, "打开串口");
#endif
            }
            finally
            {
                if (ConState != null)
                {
                    ConState(status, msg, CommType.COM);
                }

                comEdit = false;
                BeginConnection();
            }
        }

        private void BeginConnection()
        {
            mainSocket = new Socket(AddressFamily.InterNetwork,
                    SocketType.Stream, ProtocolType.Tcp);
            try
            {
                IPAddress ip = Dns.GetHostEntry(serverIP).AddressList[0];
                mainSocket.BeginConnect(ip, port, new AsyncCallback(EndConnection), mainSocket);
            }
            catch(Exception exp)
            {
                Close(exp, CommType.TCP);
#if DEBUG
                WriteLine(exp, "Socket 异步连接");
#endif
            }
        }

        public void Close(Exception exp, CommType type)
        {
            if (mainPort.IsOpen)
            {
                try
                {
                    mainPort.Close();
                }
                catch (Exception error)
                {
#if DEBUG
                    WriteLine(error, "关闭串口");
#endif
                }
            }

            try
            {
                if (mainSocket.Connected)
                {
                    mainSocket.Send(Encoding.Default.GetBytes("CLIENTEXIT"));
                }

            }
            finally
            {
                mainSocket.Close();

                if (ConState != null)
                {
                    ConState(false, exp.Message, type);
                }
            }
        }

        public void Close()
        {
            if (mainPort.IsOpen)
            {
                try
                {
                    mainPort.Close();
                }
                catch(Exception exp)
                {
#if DEBUG
                    WriteLine(exp, "关闭串口");
#endif
                }
            }

            try
            {
                if (mainSocket.Connected)
                {
                    mainSocket.Send(Encoding.Default.GetBytes("CLIENTEXIT"));
                }
            }
            finally
            {
                if (ConState != null && mainSocket.Connected)
                {
                    ConState(false, "释放Socket资源", CommType.TCP);
                    mainSocket.Close();
                }
            }
        }

        private void EndConnection(IAsyncResult ar)
        {
            Socket socket = ar.AsyncState as Socket;
            try
            {
                socket.EndConnect(ar);
                status = socket.Connected;
            }
            catch (ObjectDisposedException)
            {
                status = false;

                msg = "Socket对象已释放";
#if DEBUG
                WriteLine(new Exception("已释放了Socket对象"), "数据接受处理");
#endif

            }
            catch (SocketException exp)
            {
                status = false;

                if (exp.ErrorCode.Equals(10060))
                {
                    msg = "服务器长时间无响应";
                }
                else if (exp.ErrorCode.Equals(10061))
                {
                    msg = "服务器未开启";
                }
                else
                {
                    msg = "套接字错误引发异常";
                }
#if DEBUG
                WriteLine(new Exception("套接字错误引发异常"), "数据接受处理");
#endif
            }
            catch (Exception)
            {
                msg = "Socket异步连接错误";
                status = false;
#if DEBUG
                WriteLine(new Exception("Socket异步连接错误"), "Socket 连接EndConnection");
#endif
            }
            finally
            {
                if (ConState != null)
                {
                    ConState(status, msg, CommType.TCP);
                }
                if (status)
                {
                    BeginReceive();
                }
            }
        }

        private void BeginReceive()
        {
            if (mainSocket.Connected)
            {
                try
                {
                    Array.Clear(socketInfo.Buffers, 0, socketInfo.DataLen);
                    socketInfo.DataLen = 0;
                    mainSocket.BeginReceive(socketInfo.Buffers, 0, 1024,
                        SocketFlags.None, new AsyncCallback(EndReceive), null);
                }
                catch (ObjectDisposedException)
                {
                    status = false;

                    Close(new Exception("服务器已释放了Socket对象"), CommType.TCP);
#if DEBUG
                    WriteLine(new Exception("服务器已释放了Socket对象"), "数据接受处理");
#endif

                }
                catch (SocketException)
                {
                    status = false;

                    Close(new Exception("服务器已放弃了一个连接"), CommType.TCP);
#if DEBUG
                    WriteLine(new Exception("服务器已放弃了一个连接"), "数据接受处理");
#endif

                }
                catch (Exception)
                {
                    status = false;
                    if (ConState != null)
                    {
                        ConState(status, "Socket开始接受数据错误", CommType.TCP);
                    }
#if DEBUG
                    WriteLine(new Exception("Socket开始接受数据错误"), "异步接受数据");
#endif
                }
            }
        }

        private void EndReceive(IAsyncResult ar)
        {
            try
            {
                if (!mainSocket.Connected)
                {
                    mainSocket.Close();

                    return;
                }
                socketInfo.DataLen = mainSocket.EndReceive(ar);

                if (socketInfo.DataLen == 0)
                {
                    mainSocket.Send(Encoding.Default.GetBytes("HZKJ"));
                    BeginReceive();

                    return;
                }

                if (Encoding.Default.GetString(socketInfo.Buffers, 0,
                    socketInfo.DataLen) == "SERVERSTOP")
                {
                    status = false;
                    if (ConState != null)
                    {
                        ConState(status, "服务器主动断开", CommType.TCP);
                    }

                    Close();
                }

                ErrorBuffers = new byte[socketInfo.DataLen];
                Array.Copy(socketInfo.Buffers, 0, ErrorBuffers, 0, socketInfo.DataLen);

                OnDataArrive(new DataArraveArgs(ref ErrorBuffers,
                    socketInfo.DataLen, CommType.TCP));

                SendPort(ErrorBuffers);

                BeginReceive();
            }
            catch (ObjectDisposedException)
            {
                status = false;

                Close(new Exception("服务器已释放了Socket对象"), CommType.TCP);
#if DEBUG
                WriteLine(new Exception("服务器已释放了Socket对象"), "数据接受处理");
#endif

            }
            catch (SocketException)
            {
                status = false;

                Close(new Exception("服务器已放弃了一个连接"), CommType.TCP);
#if DEBUG
                WriteLine(new Exception("服务器已放弃了一个连接"), "数据接受处理");
#endif

            }
            catch (Exception)
            {
                status = false;

                Close(new Exception("Socket接受错误"), CommType.TCP);
#if DEBUG
                WriteLine(new Exception("Socket消息接受错误"), "数据接受处理");
#endif
            } 
        }

        public void SendPort(byte[] sDatas)
        {
            try
            {
                mainPort.Write(sDatas, 0, sDatas.Length);
            }
            catch(Exception exp)
            {
                try
                {
                    if (mainPort.IsOpen)
                    {
                        mainPort.Close();
                    }
                }
                catch
                {
#if DEBUG
                    WriteLine(exp, "串口发送数据||打开");
#endif
                }
                finally
                {
                    if (ConState != null)
                    {
                        ConState(false, exp.Message, CommType.COM);
                    }
                }
            }
        }

        public void SendSocket(byte[] sDatas)
        {
            try
            {
                mainSocket.Send(sDatas);
            }
            catch (ObjectDisposedException)
            {
                status = false;

                Close(new Exception("服务器已释放了Socket对象"), CommType.TCP);
#if DEBUG
                WriteLine(new Exception("服务器已释放了Socket对象"), "数据接受处理");
#endif

            }
            catch (SocketException)
            {
                status = false;

                Close(new Exception("套接字错误引发异常"), CommType.TCP);
#if DEBUG
                WriteLine(new Exception("套接字错误引发异常"), "数据接受处理");
#endif

            }
            catch (Exception)
            {
                if (ConState != null)
                {
                    ConState(false, "Socket消息发送错误", CommType.TCP);
                }
#if DEBUG
                WriteLine(new Exception("Socket消息发送错误"), "Scoket 数据发送");
#endif
            }
        }

        public bool Send(string msg, bool com)
        {
            string[] msgs = msg.Split(' ');

            byte[] buffers = new byte[msgs.Length];

            if (msgs.Length > 1)
            {
                try
                {
                    for (int i = 0; i < msgs.Length; i++)
                    {
                        buffers[i] = Convert.ToByte(msgs[i], 16);
                    }
                    if (!CheckPack(buffers, msgs.Length)) return false;
                }
                catch (Exception) { }
            }
            else
            {
                buffers = Encoding.Default.GetBytes(msg);
            }

            if (com)
            {
                if (!mainPort.IsOpen)
                {
                    msg = string.Empty;
                    try
                    {
                        mainPort.Open();
                    }
                    catch (Exception exp)
                    {
                        msg = "当前串口已占用|不存在";
#if DEBUG
                        WriteLine(exp, "串口打开");
#endif
                    }
                    finally
                    {
                        if (ConState != null)
                        {
                            ConState(mainPort.IsOpen, msg, CommType.COM);
                        }
                    }
                }

                SendPort(buffers);
            }
            else
            {
                if (!mainSocket.Connected)
                {
                    BeginConnection();
                }

                SendSocket( buffers);
            }

            return true;
        }

        /// <summary>
        /// 函数功能:校验和
        /// 函数名称: VadateDatas
        /// 参    数:  byte[] reDatas,int dataLen
        /// 返 回 值: bool
        /// 程 序 员: XLG
        /// 编制日期: 08/06/02
        /// 函数说明:
        ///          1, 对接受的数据进行校验
        ///          2,校验启动位,停止位,偶校验位 
        /// </summary>
        private bool CheckPack(byte[] reDatas, int dataLen)
        {
            if (reDatas[0] == 0xAA && dataLen == 14)
            {
                return true;
            }
            if (reDatas[0] != 0x68 || reDatas[5] != 0x68)
            {
                return false;
            }
            else if (reDatas[12].Equals(0x20))
            {
                return true;
            }
            else if (dataLen < 0x10)
            {
                return false;
            }
            else if (!CheckPack(ref reDatas))
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        /// <summary>
        /// 函数功能:校验接受数据长度和验证校验和
        /// 函数名称: CheckPack
        /// 参    数: 
        /// 返 回 值: static void
        /// 程 序 员: XLG
        /// 编制日期: 08/06/02
        /// 函数说明:
        ///          1, 按照规约验证校验和,数组长度   
        /// </summary>
        private bool CheckPack(ref byte[] reDatas)
        {
            short LA, LB, L;
            LA = reDatas[2];
            LA = Convert.ToInt16(LA << 8 | reDatas[1]);
            LB = reDatas[4];
            LB = Convert.ToInt16(LB << 8 | reDatas[3]);

            if (LA != LB)
            {
                return false;
            }

            L = Convert.ToInt16(LA >> 2);

            byte CS = 0;
            for (int i = 6; i <= L + 5; i++)
            {
                CS += reDatas[i];
            }

            if (CS == reDatas[L + 6])
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// Debug测试异常
        /// </summary>
        /// <param name="exp"></param>
        /// <param name="msg"></param>
        public static void WriteLine(Exception exp, string msg)
        {
            string file = Application.StartupPath + @"\Debug.ini";
            try
            {
                using (StreamWriter sw = new StreamWriter(file, true))
                {
                    string message = new string('*', 20);
                    sw.WriteLine("{0}〓{1}〓{2}", message, msg, message);
                    sw.WriteLine("Message:{0}", exp.Message);
                    sw.WriteLine("Source:{0}", exp.Source);
                    sw.WriteLine("StackTrace:{0}", exp.StackTrace);
                    sw.WriteLine("{0}〓{1}〓{2}", message, DateTime.Now, message);
                }

                System.Diagnostics.Trace.WriteLine(exp.Message);
            }
            catch
            { ;}
        }
    }
}

转载于:https://www.cnblogs.com/xiaoligeng/archive/2009/02/04/1384066.html

;