diff --git a/GeneralGommunication/ModbusAsciiServer.cs b/GeneralGommunication/ModbusAsciiServer.cs
index 8244903cf51b0afba3dd50c38894179550d6205a..0ac251928a24dc69f513d780959b75ed37fa0afa 100644
--- a/GeneralGommunication/ModbusAsciiServer.cs
+++ b/GeneralGommunication/ModbusAsciiServer.cs
@@ -24,7 +24,8 @@ namespace GeneralGommunication
             MBA_STATUS_0A = 2
         }
         ModbusAsciiStatus status;
-        ModbusRegReadWriteHandler regRead;
+        ModbusRegReadWriteHandler regRead_Holding;
+        ModbusRegReadWriteHandler regRead_Input;
         ModbusRegReadWriteHandler regWrite;
         Action<IEnumerable<byte>> sendMsg;
 
@@ -34,10 +35,14 @@ namespace GeneralGommunication
         //上一次接收数据的时间
         DateTime lastRecMsgTime;
 
-        public void Init(ModbusRegReadWriteHandler regRead, ModbusRegReadWriteHandler regWrite,
+        public void Init(
+            ModbusRegReadWriteHandler regRead_Holding,
+            ModbusRegReadWriteHandler regRead_Input,
+            ModbusRegReadWriteHandler regWrite,
             Action<IEnumerable<byte>> sendMsg, out Action<IEnumerable<byte>> recMsg)
         {
-            this.regRead = regRead;
+            this.regRead_Holding = regRead_Holding;
+            this.regRead_Input = regRead_Input;
             this.regWrite = regWrite;
             this.sendMsg = sendMsg;
             recMsg = RecMsg;
@@ -54,7 +59,7 @@ namespace GeneralGommunication
 
 
         /// <summary>
-        /// Read REGs
+        /// Read Holding REGs
         /// </summary>
         /// <param name="buf">传入通讯字元</param>
         /// <param name="startIndex"></param>
@@ -118,7 +123,12 @@ namespace GeneralGommunication
             midBuf.Add((byte)(number * 2));
 
             UInt16[] regValues = new UInt16[number];
-            bool ret = this.regRead(deviceNo, startAddr, regValues);
+            if (this.regRead_Holding == null)
+            {
+                //读取失败,没有设备,不用回复
+                return;
+            }
+            bool ret = this.regRead_Holding(deviceNo, startAddr, regValues);
             if (!ret)
             {
                 //读取失败,没有设备,不用回复
@@ -133,7 +143,90 @@ namespace GeneralGommunication
             Modbus_AddLrcAndSend(midBuf);
         }
 
+        /// <summary>
+        /// Read Input REGs
+        /// </summary>
+        /// <param name="buf">传入通讯字元</param>
+        /// <param name="startIndex"></param>
+        /// <param name="len">buf长度</param>
+        void Modbus_Func04(IEnumerable<byte> buf, int startIndex, int len)
+        {
+
+            //请求
+            //0.	':' 0x3A
+            //1.	slave address : 2bytes ascii 
+            //2.	Function : 2bytes ascii 
+            //3.	Starting Address Hi : 2bytes ascii 
+            //4.	Starting Address Lo : 2bytes ascii 
+            //5.	Number of Register Hi : 2bytes ascii 
+            //6.	Number of Register Lo : 2bytes ascii 
+            //7.	LRC : 2bytes ascii 
+            //8.	0x0D 0x0A
+
+            //响应
+            //0.	':' 0x3A
+            //1.	slave address : 2bytes ascii 
+            //2.	Function : 2bytes ascii 
+            //3.	Number * 2 : 2bytes ascii 
+
+            //下面重复 Number 次
+            //4.	Data Hi : 2bytes ascii  
+            //5.	Data Lo : 2bytes ascii 
+
+            //6.	LRC : 2bytes ascii 
+            //7.	0x0D 0x0A
+
+
+            //example: 下面为 ASCII
+            //请求
+            //: 01 03 00 01 00 01 ?? (0X0D) (0X0A)
+            //响应
+            //: 01 03 02 12 34 ?? (0X0D) (0X0A)
+
+            //buf 已经是 ascii转hex 后结果。 从 slave address 开始,没有LRC
 
+            if (len < 6)
+            {
+                Modbus_DefaultCallback(buf, startIndex, MB_ERR_LEN);//指令异常
+                return;
+            }
+
+            byte deviceNo = buf.ElementAt(startIndex);
+            UInt16 startAddr = buf.ToUInt16_Big_Endian(startIndex + 2);
+            UInt16 number = buf.ToUInt16_Big_Endian(startIndex + 4);
+
+            if (number == 0)
+            {
+                Modbus_DefaultCallback(buf, startIndex, MB_ERR_NUM_0);//指令异常
+                return;
+            }
+            if (number > 50)//限制数量,因为缓存区不够大
+                number = 50;
+            List<byte> midBuf = new List<byte>();
+            midBuf.Add(deviceNo);
+            midBuf.Add(0x04);
+            midBuf.Add((byte)(number * 2));
+
+            UInt16[] regValues = new UInt16[number];
+            if (this.regRead_Input == null)
+            { 
+                //读取失败,没有设备,不用回复
+                return;
+            }
+            bool ret = this.regRead_Input(deviceNo, startAddr, regValues);
+            if (!ret)
+            {
+                //读取失败,没有设备,不用回复
+                return;
+            }
+
+            for (int i = 0; i < number; i++)
+            {
+                midBuf.AddRange(regValues[i].GetBytes_Big_endian());
+            }
+
+            Modbus_AddLrcAndSend(midBuf);
+        }
         /// <summary>
         /// Write Single REG
         /// </summary>
@@ -183,6 +276,8 @@ namespace GeneralGommunication
             UInt16 regValue = buf.ToUInt16_Big_Endian(startIndex + 4);
 
             UInt16[] regValues = new UInt16[] { regValue };
+            if (this.regWrite == null)
+                return;//写入失败,没有设备,不用回复
             bool ret = this.regWrite(deviceNo, startAddr, regValues);
             if (!ret)
             {
@@ -282,6 +377,8 @@ namespace GeneralGommunication
                 index += 2;
                 regValues[i] = regValue;
             }
+            if (this.regWrite == null)
+                return;//写入失败,没有设备,不用回复
 
             bool ret = this.regWrite(deviceNo, startAddr, regValues);
             if (!ret)
@@ -470,6 +567,9 @@ namespace GeneralGommunication
                 case 0x03:
                     Modbus_Func03(midBuf, 0, adu_len);
                     break;
+                case 0x04:
+                    Modbus_Func04(midBuf, 0, adu_len);
+                    break;
                 //case 0x05:
                 //	Modbus_Func05(buf, adu_len);
                 //	break;
diff --git a/GeneralGommunication/ModbusRtuServer.cs b/GeneralGommunication/ModbusRtuServer.cs
index f6b6436aa21667edf2f519961d62f376eda6b8c0..d127e5dc85818499576461608aa0e7bbb518723e 100644
--- a/GeneralGommunication/ModbusRtuServer.cs
+++ b/GeneralGommunication/ModbusRtuServer.cs
@@ -19,7 +19,7 @@ namespace GeneralGommunication
         const byte MB_ERR_CNT = 0x03;//字节数!=寄存器数量*2
         const byte MB_ERR_NOFUNC = 0x05;//没有这个func
 
-       
+        ModbusRegReadWriteHandler regRead_Input;
         ModbusRegReadWriteHandler regRead;
         ModbusRegReadWriteHandler regWrite;
         Action<IEnumerable<byte>> sendMsg;
@@ -30,10 +30,11 @@ namespace GeneralGommunication
         System.Threading.Timer timer3d5t;//通讯包的 3.5T 时间间隔。 实际只是 15ms定时而已
 
 
-        public void Init(ModbusRegReadWriteHandler regRead, ModbusRegReadWriteHandler regWrite,
+        public void Init(ModbusRegReadWriteHandler regRead, ModbusRegReadWriteHandler regRead_Input, ModbusRegReadWriteHandler regWrite,
             Action<IEnumerable<byte>> sendMsg, out Action<IEnumerable<byte>> recMsg)
         {
             this.regRead = regRead;
+            this.regRead_Input = regRead_Input;
             this.regWrite = regWrite;
             this.sendMsg = sendMsg;
             recMsg = RecMsg;
@@ -135,6 +136,13 @@ namespace GeneralGommunication
             midBuf.Add((byte)(number * 2));
 
             UInt16[] regValues = new UInt16[number];
+            if (this.regRead == null)
+            {
+                //读取失败,没有设备,不用回复
+                logger.Debug($"REQ 读取失败,没有设置regRead,不用回复");
+                sendBuf = null;
+                return req_len;
+            }
             bool ret = this.regRead(deviceNo, startAddr, regValues);
             if (!ret)
             {
@@ -154,7 +162,109 @@ namespace GeneralGommunication
             //Modbus_AddCrcAndSend(midBuf);
         }
 
+        /// <summary>
+        /// 读寄存器, 返回已经处理的长度
+        /// </summary>
+        /// <param name="buf">接收缓冲</param>
+        /// <param name="startIndex">数据开始序号</param>
+        /// <param name="len">数据长度</param>
+        /// <returns></returns>
+        int Modbus_Func04(IEnumerable<byte> buf, int startIndex, int len, out byte[] sendBuf)
+        {
+            //请求
+            //1.	slave address : 1byte
+            //2.	Function : 1byte
+            //3.	Starting Address Hi : 1byte
+            //4.	Starting Address Lo : 1byte
+            //5.	Number of Register Hi : 1byte
+            //6.	Number of Register Lo : 1byte
+            //7.	CRC16 : 2bytes
+
+            //响应
+            //1.	slave address : 1byte
+            //2.	Function : 1byte
+            //3.	Number * 2 : 1byte 
+
+            //下面重复 Number 次
+            //4.	Data Hi : 1byte  
+            //5.	Data Lo : 1byte  
+
+            //6.	CRC16 : 2bytes
+
+            //example:
+            //请求
+            //01 03 00 01 00 01 ?? ??
+            //响应
+            //01 03 02 12 34 ?? ??
+
+            int req_len = 8;
+            //buf 从 slave address 开始
+            if (len < req_len)
+            {
+                logger.Error($"REQ 指令字节数不足");
+                sendBuf = Modbus_DefaultCallback(buf, startIndex, MB_ERR_LEN);//指令异常
+                return len;
+            }
+
+
+            //CRC
+            int adu_len = req_len - 2;//去除crc后的数据包长
+
+            UInt16 crc = buf.CRC16(startIndex, req_len - 2);
+            UInt16 rec_crc = buf.ToUInt16_Little_Endian(startIndex + req_len - 2);//CRC 是 小端模式
+
+            if (crc != rec_crc)
+            {
+                logger.Error($"REQ CRC 校验出错 接收:{rec_crc:X4} 计算:{crc:X4}");
+
+                sendBuf = Modbus_DefaultCallback(buf, startIndex, MB_ERR_LRC);//指令异常
+                return len;//指令异常,应该全部删除
+            }
+
+
+            byte deviceNo = recBuf[0];
+            UInt16 startAddr = buf.ToUInt16_Big_Endian(startIndex + 2);
+            UInt16 number = buf.ToUInt16_Big_Endian(startIndex + 4);
 
+            if (number == 0)
+            {
+                logger.Error($"REQ 没有任何寄存器");
+                sendBuf = Modbus_DefaultCallback(buf, startIndex, MB_ERR_NUM_0);//指令异常
+                return req_len;
+            }
+            if (number > 50)//限制数量,因为缓存区不够大
+                number = 50;
+            List<byte> midBuf = new List<byte>();
+            midBuf.Add(deviceNo);
+            midBuf.Add(0x04);
+            midBuf.Add((byte)(number * 2));
+
+            UInt16[] regValues = new UInt16[number];
+            if (this.regRead_Input == null)
+            {
+                //读取失败,没有设备,不用回复
+                logger.Debug($"REQ 读取失败,没有设置regRead,不用回复");
+                sendBuf = null;
+                return req_len;
+            }
+            bool ret = this.regRead_Input(deviceNo, startAddr, regValues);
+            if (!ret)
+            {
+                //读取失败,没有设备,不用回复
+                logger.Debug($"REQ 读取失败,没有设备,不用回复");
+                sendBuf = null;
+                return req_len;
+            }
+
+            for (int i = 0; i < number; i++)
+            {
+                midBuf.AddRange(regValues[i].GetBytes_Big_endian());
+            }
+
+            sendBuf = midBuf.ToArray();
+            return req_len;
+            //Modbus_AddCrcAndSend(midBuf);
+        }
         /// <summary>
         /// Write Single REG
         /// </summary>
diff --git a/GeneralGommunication/ModbusServer.cs b/GeneralGommunication/ModbusServer.cs
index d1a85a7d5659b6cbf6d8d72d73cfc376318e49d8..e8508f2ae66653beb2f0536b6d54a711acdf0613 100644
--- a/GeneralGommunication/ModbusServer.cs
+++ b/GeneralGommunication/ModbusServer.cs
@@ -8,7 +8,9 @@ namespace GeneralGommunication
 {
     public interface IModbusServer
     {
-        void Init(ModbusRegReadWriteHandler regRead, ModbusRegReadWriteHandler regWrite, 
+        void Init(ModbusRegReadWriteHandler regRead_Holding,
+            ModbusRegReadWriteHandler regRead_Input, 
+            ModbusRegReadWriteHandler regWrite, 
             Action<IEnumerable<byte>> sendMsg, out Action<IEnumerable<byte>> recMsg);
     }