예제 #1
0
        void Run(object obj)
        {
            var server = obj as Socket;

            if (server != null)
            {
                #region SocketConnected
                SocketConnected?.Invoke(this, new SocketEventArgs(server));
                #endregion

                List <byte> lstResponse = new List <byte>();
                var         prev        = DateTime.Now;
                var         chr         = new Chattering()
                {
                    ChatteringTime = DisconnectCheckTime
                };

                bool IsThStart = true;

                chr.StateChanged += (o, s) => { if (!s.Value)
                                                {
                                                    IsThStart = false;
                                                }
                };
                while (IsThStart)
                {
                    try
                    {
                        #region DataRead
                        if (server.Available > 0)
                        {
                            try
                            {
                                int n = server.Receive(baResponse);
                                for (int i = 0; i < n; i++)
                                {
                                    lstResponse.Add(baResponse[i]);
                                }
                                prev = DateTime.Now;
                            }
                            catch (TimeoutException) { }
                        }
                        #endregion

                        #region Modbus Parse
                        if (lstResponse.Count >= 10)
                        {
                            int            Slave        = lstResponse[6];
                            ModbusFunction Function     = (ModbusFunction)lstResponse[7];
                            int            StartAddress = (lstResponse[8] << 8) | lstResponse[9];

                            switch (Function)
                            {
                            case ModbusFunction.BITREAD_F1:
                            case ModbusFunction.BITREAD_F2:
                                #region BitRead
                                if (lstResponse.Count == 12)
                                {
                                    int Length = (lstResponse[10] << 8) | lstResponse[11];

                                    if (BitReadRequest != null)
                                    {
                                        var args = new BitReadRequestArgs(lstResponse.ToArray());
                                        BitReadRequest?.Invoke(this, args);

                                        if (args.Success && args.ResponseData != null && args.ResponseData.Length == args.Length)
                                        {
                                            #region MakeData
                                            List <byte> Datas = new List <byte>();
                                            int         nlen  = args.ResponseData.Length / 8;
                                            nlen += (args.ResponseData.Length % 8 == 0) ? 0 : 1;
                                            for (int i = 0; i < nlen; i++)
                                            {
                                                byte val = 0;
                                                for (int j = (i * 8), nTemp = 0; j < args.ResponseData.Length && j < (i * 8) + 8; j++, nTemp++)
                                                {
                                                    if (args.ResponseData[j])
                                                    {
                                                        val |= Convert.ToByte(Math.Pow(2, nTemp));
                                                    }
                                                }
                                                Datas.Add(val);
                                            }
                                            #endregion
                                            #region Write
                                            List <byte> ret = new List <byte>();
                                            ret.Add(0);
                                            ret.Add(0);
                                            ret.Add(0);
                                            ret.Add(0);
                                            ret.Add((byte)(((nlen + 3) & 0xFF00) >> 8));
                                            ret.Add((byte)(((nlen + 3) & 0x00FF)));
                                            ret.Add((byte)Slave);
                                            ret.Add((byte)Function);
                                            ret.Add((byte)Datas.Count);
                                            ret.AddRange(Datas.ToArray());

                                            byte[] send = ret.ToArray();
                                            server.Send(send);
                                            #endregion
                                        }
                                    }
                                    lstResponse.Clear();
                                }
                                #endregion
                                break;

                            case ModbusFunction.WORDREAD_F3:
                            case ModbusFunction.WORDREAD_F4:
                                #region WordRead
                                if (lstResponse.Count == 12)
                                {
                                    int Length = (lstResponse[10] << 8) | lstResponse[11];

                                    if (WordReadRequest != null)
                                    {
                                        var args = new WordReadRequestArgs(lstResponse.ToArray());
                                        WordReadRequest?.Invoke(this, args);

                                        if (args.Success && args.ResponseData != null && args.ResponseData.Length == args.Length)
                                        {
                                            #region MakeData
                                            List <byte> Datas = new List <byte>();
                                            for (int i = 0; i < args.ResponseData.Length; i++)
                                            {
                                                Datas.Add((byte)((args.ResponseData[i] & 0xFF00) >> 8));
                                                Datas.Add((byte)((args.ResponseData[i] & 0x00FF)));
                                            }
                                            #endregion
                                            #region Write
                                            int         nlen = Length * 2;
                                            List <byte> ret  = new List <byte>();
                                            ret.Add(0);
                                            ret.Add(0);
                                            ret.Add(0);
                                            ret.Add(0);
                                            ret.Add((byte)(((nlen + 3) & 0xFF00) >> 8));
                                            ret.Add((byte)(((nlen + 3) & 0x00FF)));
                                            ret.Add((byte)Slave);
                                            ret.Add((byte)Function);
                                            ret.Add((byte)Datas.Count);
                                            ret.AddRange(Datas.ToArray());

                                            byte[] send = ret.ToArray();
                                            server.Send(send);
                                            #endregion
                                        }
                                    }
                                    lstResponse.Clear();
                                }
                                #endregion
                                break;

                            case ModbusFunction.BITWRITE_F5:
                                #region BitWrite
                                if (lstResponse.Count == 12)
                                {
                                    int WriteValue = (lstResponse[10] << 8) | lstResponse[11];
                                    if (BitWriteRequest != null)
                                    {
                                        var args = new BitWriteRequestArgs(lstResponse.ToArray());
                                        BitWriteRequest?.Invoke(this, args);

                                        if (args.Success)
                                        {
                                            #region Write
                                            int         nv  = args.WriteValue ? 0xFF00 : 0;
                                            List <byte> ret = new List <byte>();
                                            ret.Add(0);
                                            ret.Add(0);
                                            ret.Add(0);
                                            ret.Add(0);
                                            ret.Add(0);
                                            ret.Add(6);
                                            ret.Add((byte)Slave);
                                            ret.Add((byte)Function);
                                            ret.Add((byte)((StartAddress & 0xFF00) >> 8));
                                            ret.Add((byte)((StartAddress & 0x00FF)));
                                            ret.Add((byte)((nv & 0xFF00) >> 8));
                                            ret.Add((byte)((nv & 0x00FF)));

                                            byte[] send = ret.ToArray();
                                            server.Send(send);
                                            #endregion
                                        }
                                    }
                                    lstResponse.Clear();
                                }
                                #endregion
                                break;

                            case ModbusFunction.WORDWRITE_F6:
                                #region WordWrite
                                if (lstResponse.Count == 12)
                                {
                                    int WriteValue = (lstResponse[10] << 8) | lstResponse[11];

                                    if (WordWriteRequest != null)
                                    {
                                        var args = new WordWriteRequestArgs(lstResponse.ToArray());
                                        WordWriteRequest?.Invoke(this, args);

                                        if (args.Success)
                                        {
                                            #region Write
                                            List <byte> ret = new List <byte>();
                                            ret.Add(0);
                                            ret.Add(0);
                                            ret.Add(0);
                                            ret.Add(0);
                                            ret.Add(0);
                                            ret.Add(6);
                                            ret.Add((byte)args.Slave);
                                            ret.Add((byte)args.Function);
                                            ret.Add((byte)((args.StartAddress & 0xFF00) >> 8));
                                            ret.Add((byte)((args.StartAddress & 0x00FF)));
                                            ret.Add((byte)((args.WriteValue & 0xFF00) >> 8));
                                            ret.Add((byte)((args.WriteValue & 0x00FF)));

                                            byte[] send = ret.ToArray();
                                            server.Send(send);
                                            #endregion
                                        }
                                    }
                                    lstResponse.Clear();
                                }
                                #endregion
                                break;

                            case ModbusFunction.MULTIBITWRITE_F15:
                                #region MultiBitWrite
                                if (lstResponse.Count >= 13)
                                {
                                    int ByteCount = lstResponse[12];
                                    if (lstResponse.Count >= 13 + ByteCount)
                                    {
                                        var args = new MultiBitWriteRequestArgs(lstResponse.ToArray());
                                        if (MultiBitWriteRequest != null)
                                        {
                                            MultiBitWriteRequest?.Invoke(this, args);

                                            if (args.Success)
                                            {
                                                #region Write
                                                List <byte> ret = new List <byte>();
                                                ret.Add(0);
                                                ret.Add(0);
                                                ret.Add(0);
                                                ret.Add(0);
                                                ret.Add(0);
                                                ret.Add(6);
                                                ret.Add((byte)args.Slave);
                                                ret.Add((byte)args.Function);
                                                ret.Add((byte)((args.StartAddress & 0xFF00) >> 8));
                                                ret.Add((byte)((args.StartAddress & 0x00FF)));
                                                ret.Add((byte)((args.Length & 0xFF00) >> 8));
                                                ret.Add((byte)((args.Length & 0x00FF)));

                                                byte[] send = ret.ToArray();
                                                server.Send(send);
                                                #endregion
                                            }
                                        }
                                        lstResponse.Clear();
                                    }
                                }
                                #endregion
                                break;

                            case ModbusFunction.MULTIWORDWRITE_F16:
                                #region MultiWordWrite
                                if (lstResponse.Count >= 13)
                                {
                                    int ByteCount = lstResponse[12];
                                    if (lstResponse.Count >= 13 + ByteCount)
                                    {
                                        if (MultiWordWriteRequest != null)
                                        {
                                            var args = new MultiWordWriteRequestArgs(lstResponse.ToArray());
                                            MultiWordWriteRequest?.Invoke(this, args);

                                            if (args.Success)
                                            {
                                                #region Write
                                                List <byte> ret = new List <byte>();
                                                ret.Add(0);
                                                ret.Add(0);
                                                ret.Add(0);
                                                ret.Add(0);
                                                ret.Add(0);
                                                ret.Add(6);
                                                ret.Add((byte)args.Slave);
                                                ret.Add((byte)args.Function);
                                                ret.Add((byte)((args.StartAddress & 0xFF00) >> 8));
                                                ret.Add((byte)((args.StartAddress & 0x00FF)));
                                                ret.Add((byte)((args.Length & 0xFF00) >> 8));
                                                ret.Add((byte)((args.Length & 0x00FF)));

                                                byte[] send = ret.ToArray();
                                                server.Send(send);
                                                #endregion
                                            }
                                        }
                                        lstResponse.Clear();
                                    }
                                }
                                #endregion
                                break;

                            case ModbusFunction.WORDBITSET_F26:
                                #region WordBitSet
                                if (lstResponse.Count == 13)
                                {
                                    if (WordBitSetRequest != null)
                                    {
                                        var args = new WordBitSetRequestArgs(lstResponse.ToArray());
                                        WordBitSetRequest?.Invoke(this, args);

                                        if (args.Success)
                                        {
                                            #region Write
                                            int         nv  = args.WriteValue ? 0xFF00 : 0;
                                            List <byte> ret = new List <byte>();
                                            ret.Add(0);
                                            ret.Add(0);
                                            ret.Add(0);
                                            ret.Add(0);
                                            ret.Add(0);
                                            ret.Add(6);
                                            ret.Add((byte)args.Slave);
                                            ret.Add((byte)args.Function);
                                            ret.Add((byte)((args.StartAddress & 0xFF00) >> 8));
                                            ret.Add((byte)((args.StartAddress & 0x00FF)));
                                            ret.Add((byte)((nv & 0xFF00) >> 8));
                                            ret.Add((byte)((nv & 0x00FF)));

                                            byte[] send = ret.ToArray();
                                            server.Send(send);
                                            #endregion
                                        }
                                    }
                                    lstResponse.Clear();
                                }
                                #endregion
                                break;
                            }
                        }
                        #endregion

                        #region Buffer Clear
                        if ((DateTime.Now - prev).TotalMilliseconds >= 50 && lstResponse.Count > 0)
                        {
                            lstResponse.Clear();
                        }
                        #endregion

                        chr.Set(NetworkTool.IsSocketConnected(server));
                    }
                    catch (SocketException ex)
                    {
                        if (ex.SocketErrorCode == SocketError.TimedOut)
                        {
                        }
                        else if (ex.SocketErrorCode == SocketError.ConnectionReset)
                        {
                        }
                        else if (ex.SocketErrorCode == SocketError.ConnectionAborted)
                        {
                            IsThStart = false;
                        }
                    }
                    catch { }
                    Thread.Sleep(10);
                }

                #region Socket Closed
                if (server.Connected)
                {
                    server.Close();
                }
                SocketDisconnected?.Invoke(this, new SocketEventArgs(server));
                #endregion
            }
        }
예제 #2
0
        void Run(object obj)
        {
            var server = obj as Socket;

            if (server != null)
            {
                #region SocketConnected
                SocketConnected?.Invoke(this, new SocketEventArgs(server));
                #endregion

                var lstResponse = new List <byte>();
                var prev        = DateTime.Now;
                var chr         = new Chattering()
                {
                    ChatteringTime = DisconnectCheckTime
                };

                var bDLE      = false;
                var bValid    = false;
                var IsThStart = true;

                chr.StateChanged += (o, s) => { if (!s.Value)
                                                {
                                                    IsThStart = false;
                                                }
                };
                while (IsThStart)
                {
                    try
                    {
                        #region DataRead
                        while (server.Available > 0)
                        {
                            try
                            {
                                int n = server.Receive(baResponse);
                                for (int i = 0; i < n; i++)
                                {
                                    var d = baResponse[i];
                                    var v = d;

                                    if (bDLE)
                                    {
                                        bDLE = false;
                                        if (v >= 0x10)
                                        {
                                            v -= 0x10;
                                        }
                                        else
                                        {
                                            bValid = false;
                                        }
                                    }

                                    switch (d)
                                    {
                                        #region STX
                                    case 0x02:
                                        lstResponse.Clear();
                                        bValid = true;
                                        break;

                                        #endregion
                                        #region ETX
                                    case 0x03:
                                    {
                                        if (bValid)
                                        {
                                            if (lstResponse.Count >= 3)
                                            {
                                                var sum = (byte)(lstResponse.GetRange(0, lstResponse.Count - 1).Select(x => (int)x).Sum() & 0xFF);
                                                if (sum == lstResponse[lstResponse.Count - 1])
                                                {
                                                    byte   slave = lstResponse[0];
                                                    byte   cmd   = lstResponse[1];
                                                    string msg   = MessageEncoding.GetString(lstResponse.ToArray(), 2, lstResponse.Count - 3);

                                                    if (MessageRequest != null)
                                                    {
                                                        var args = new MessageRequestArgs(slave, cmd, msg);
                                                        MessageRequest.Invoke(this, args);

                                                        if (!string.IsNullOrEmpty(args.ResponseMessage))
                                                        {
                                                            server.Send(TextComm.MakePacket(MessageEncoding, slave, cmd, args.ResponseMessage));
                                                        }
                                                    }
                                                }
                                            }
                                        }

                                        bValid = false;
                                        bDLE   = false;
                                        lstResponse.Clear();
                                    }
                                    break;

                                        #endregion
                                        #region DLE
                                    case 0x10:
                                        bDLE = true;
                                        break;

                                        #endregion
                                        #region Default
                                    default:
                                        lstResponse.Add(v);
                                        break;
                                        #endregion
                                    }
                                }
                            }
                            catch (TimeoutException) { }
                            prev = DateTime.Now;
                        }
                        #endregion

                        #region Buffer Clear
                        if ((DateTime.Now - prev).TotalMilliseconds >= 50 && lstResponse.Count > 0)
                        {
                            lstResponse.Clear();
                        }
                        #endregion

                        chr.Set(NetworkTool.IsSocketConnected(server));
                    }
                    catch (SocketException ex)
                    {
                        if (ex.SocketErrorCode == SocketError.TimedOut)
                        {
                        }
                        else if (ex.SocketErrorCode == SocketError.ConnectionReset)
                        {
                        }
                        else if (ex.SocketErrorCode == SocketError.ConnectionAborted)
                        {
                            IsThStart = false;
                        }
                    }
                    catch { }
                    Thread.Sleep(10);
                }

                #region Socket Closed
                if (server.Connected)
                {
                    server.Close();
                }
                SocketDisconnected?.Invoke(this, new SocketEventArgs(server));
                #endregion
            }
        }