private static void ModbusListener_DoWork(object sender, DoWorkEventArgs e) { var worker = (BackgroundWorker)sender; if (!(e.Argument is TcpTuning parameters)) { return; } // var listener = new TcpListener(IPAddress.Any, parameters.Port) { Server = { SendTimeout = parameters.SendTimeout, ReceiveTimeout = parameters.ReceiveTimeout } }; // do { Thread.Sleep(parameters.WaitForConnect); try { listener.Start(10); // Buffer for reading data var bytes = new byte[256]; while (!listener.Pending()) { Thread.Sleep(1); if (!worker.CancellationPending) { continue; } listener.Stop(); worker.ReportProgress(0, "Not listening"); return; } var clientData = listener.AcceptTcpClient(); // создаем отдельный поток для каждого подключения клиента ThreadPool.QueueUserWorkItem(arg => { try { // Get a stream object for reading and writing var stream = clientData.GetStream(); int count; // Loop to receive all the data sent by the client. while ((count = stream.Read(bytes, 0, bytes.Length)) != 0) { Thread.Sleep(1); var list = new List <string>(); for (var i = 0; i < count; i++) { list.Add(string.Format("{0}", bytes[i])); } if (count < 6) { continue; } var header1 = Convert.ToUInt16(bytes[0] * 256 + bytes[1]); var header2 = Convert.ToUInt16(bytes[2] * 256 + bytes[3]); var packetLen = Convert.ToUInt16(bytes[4] * 256 + bytes[5]); if (count != packetLen + 6) { continue; } var nodeAddr = bytes[6]; var funcCode = bytes[7]; var startAddr = Convert.ToUInt16(bytes[8] * 256 + bytes[9]); var regCount = Convert.ToUInt16(bytes[10] * 256 + bytes[11]); var singleValue = Convert.ToUInt16(bytes[10] * 256 + bytes[11]); List <byte> answer; byte bytesCount; byte[] msg; switch (funcCode) { case 3: // - read holding registers case 4: // - read input registers answer = new List <byte>(); answer.AddRange(BitConverter.GetBytes(Modbus.Swap(header1))); answer.AddRange(BitConverter.GetBytes(Modbus.Swap(header2))); bytesCount = Convert.ToByte(regCount * 2); packetLen = Convert.ToUInt16(bytesCount + 3); answer.AddRange(BitConverter.GetBytes(Modbus.Swap(packetLen))); answer.Add(nodeAddr); answer.Add(funcCode); answer.Add(bytesCount); // for (ushort i = 0; i < regCount; i++) { var regAddr = Modbus.ModifyToModbusRegisterAddress((ushort)(i + startAddr), (ModbusTable)funcCode); ushort value = Modbus.GetRegisterValue(nodeAddr, regAddr); answer.AddRange(BitConverter.GetBytes(value)); } // msg = answer.ToArray(); stream.Write(msg, 0, msg.Length); break; //case 6: // write one register // Modbus.SetRegisterValue(nodeAddr, Modbus.ModifyToModbusRegisterAddress(startAddr, ModbusTable.Holdings), singleValue); // //------------------- // answer = new List<byte>(); // answer.AddRange(BitConverter.GetBytes(Modbus.Swap(header1))); // answer.AddRange(BitConverter.GetBytes(Modbus.Swap(header2))); // answer.AddRange(BitConverter.GetBytes(Modbus.Swap(6))); // answer.Add(nodeAddr); // answer.Add(funcCode); // answer.AddRange(BitConverter.GetBytes(Modbus.Swap(startAddr))); // answer.AddRange(BitConverter.GetBytes(Modbus.Swap(regCount))); // msg = answer.ToArray(); // stream.Write(msg, 0, msg.Length); // break; case 16: // write several registers var n = 13; ushort addr = startAddr; for (ushort i = 0; i < regCount; i++) { var regAddr = Modbus.ModifyToModbusRegisterAddress(addr, ModbusTable.Holdings); ushort value = BitConverter.ToUInt16(bytes, n); Modbus.SetRegisterValue(nodeAddr, regAddr, value); n += 2; // коррекция позиции смещения в принятых данных для записи addr += 1; } if (regCount == 2) { var regAddr = Modbus.ModifyToModbusRegisterAddress(startAddr, ModbusTable.Holdings); var value = (float)Modbus.TypedValueFromRegistersArray(nodeAddr, regAddr, typeof(float)); Modbus.SetParamValue(new ParamAddr(nodeAddr, regAddr), string.Format(CultureInfo.GetCultureInfo("en-US"), "{0}", value)); } //------------------- answer = new List <byte>(); answer.AddRange(BitConverter.GetBytes(Modbus.Swap(header1))); answer.AddRange(BitConverter.GetBytes(Modbus.Swap(header2))); answer.AddRange(BitConverter.GetBytes(Modbus.Swap(6))); answer.Add(nodeAddr); answer.Add(funcCode); answer.AddRange(BitConverter.GetBytes(Modbus.Swap(startAddr))); answer.AddRange(BitConverter.GetBytes(Modbus.Swap(regCount))); msg = answer.ToArray(); stream.Write(msg, 0, msg.Length); break; } } // Shutdown and end connection clientData.Close(); } catch (Exception ex) { if (!worker.CancellationPending) { worker.ReportProgress(0, ex.Message); } } }); } catch (SocketException ex) { if (!worker.CancellationPending) { worker.ReportProgress(0, ex.Message); } break; } } while (!worker.CancellationPending); listener.Stop(); }