Нужна критика и совет по оптимизации работы класса на сокетах - C#

Узнай цену своей работы

Формулировка задачи:

Написал класс для работы с устройствами по протоколу Modbus TCP. Читаю регистры (один регистр это два байта) 9999 регистров моя программа читает более секунды, это не учитывая, что полученный результат нужно складывать в массив отдельный. По сути же, она должна в пару десятков миллисекунд отрабатывать. Program.cs
Листинг программы
  1. static void Main(string[] args)
  2. {
  3. try
  4. {
  5. ModbusTCP device = new ModbusTCP();
  6. device.Connect(502, 1, "192.168.1.21", 1, true, 1000);
  7. ushort[] registers = new ushort[9999];
  8. DateTime start = DateTime.Now;
  9. for (int i = 0; i < 80; i++)
  10. {
  11. device.ReadUsignedHoldingRegisters((ushort)(40001 + i * 125), 125);
  12. }
  13. DateTime finish = DateTime.Now;
  14. Console.WriteLine(finish - start);
  15. Console.ReadKey();
  16. }
  17. catch(Exception ex)
  18. {
  19. Console.WriteLine(ex.ToString());
  20. }
ModbusTCP.cs
Листинг программы
  1. public class ModbusTCP
  2. {
  3. private int port;
  4. private byte modbusStation;
  5. private string ipAddress;
  6. private ushort shift; //отсчет регистров с 0 или с 1
  7. private bool byteOrder; //порядок байт
  8. public Socket Socket { get; set; }
  9. public ModbusTCP() { }
  10. public void Connect(int _port, byte _modbusStation, string _ipAddress, ushort _shift, bool _byteOrder, int timeout)
  11. {
  12. try
  13. {
  14. port = _port;
  15. modbusStation = _modbusStation;
  16. shift = _shift;
  17. byteOrder = _byteOrder;
  18. ipAddress = _ipAddress;
  19. IPEndPoint ipPoint = new IPEndPoint(IPAddress.Parse(ipAddress), port);
  20. Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  21. Socket.ReceiveTimeout = timeout;
  22. Socket.Connect(ipPoint);
  23. }
  24. catch
  25. {
  26. }
  27. }
  28. public ushort[] ReadUsignedHoldingRegisters(ushort firstRegister, ushort amountRegisters)
  29. {
  30. if (firstRegister >= 40000 && firstRegister < 50000) firstRegister -= 40000;
  31. byte[] dataReceive = SendReceive(CreateDataForReadHoldingRegisters(firstRegister, amountRegisters));
  32. ushort[] dataUshort = new ushort[amountRegisters];
  33. for (int i = 0; i < amountRegisters; i++)
  34. {
  35. byte[] byteTemp = new byte[2];
  36. if (byteOrder) byteTemp = new byte[2] { dataReceive[i * 2 + 10], dataReceive[i * 2 + 9] };
  37. else byteTemp = new byte[2] { dataReceive[i * 2 + 9], dataReceive[i * 2 + 10] };
  38. dataUshort[i] = BitConverter.ToUInt16(byteTemp, 0);
  39. }
  40. return dataUshort;
  41. }
  42. private List<byte[]> CreateDataForReadHoldingRegisters(ushort firstRegister, ushort amountRegisters)
  43. {
  44. byte[] dataSend = new byte[12]; //запрос на чтение
  45. byte[] dataReceive = new byte[9 + amountRegisters * 2]; //ответ от устройства
  46. firstRegister -= shift; //адресс первого регистра в соответствии со сдвигом
  47. //Формирую запрос
  48. //идентификатор транзакции
  49. dataSend[0] = 30;
  50. dataSend[1] = 0;
  51. //идентификатор протокола
  52. dataSend[2] = 0;
  53. dataSend[3] = 0;
  54. //длина сообщения
  55. dataSend[4] = 0;
  56. dataSend[5] = 6;
  57. //адрес устройства
  58. dataSend[6] = modbusStation;
  59. //функция
  60. dataSend[7] = 3;
  61. //адрес первого регистра
  62. dataSend[8] = BitConverter.GetBytes(firstRegister)[1];
  63. dataSend[9] = BitConverter.GetBytes(firstRegister)[0];
  64. //количество необходимых регистров
  65. dataSend[10] = BitConverter.GetBytes(amountRegisters)[1];
  66. dataSend[11] = BitConverter.GetBytes(amountRegisters)[0];
  67. return new List<byte[]>() { dataSend, dataReceive };
  68. }
  69. private byte[] SendReceive(List<byte[]> data)
  70. {
  71. Socket.Send(data[0]);
  72. Socket.Receive(data[1]);
  73. return data[1];
  74. }

Решение задачи: «Нужна критика и совет по оптимизации работы класса на сокетах»

textual
Листинг программы
  1.         public void Read(ushort firstRegister, ushort amountRegisters)
  2.         {
  3.             if (firstRegister >= 40000 && firstRegister < 50000) firstRegister -= 40000;
  4.             byte[] dataSend = new byte[12]; //запрос на чтение
  5.  
  6.             byte[] dataReceive = new byte[9 + amountRegisters * 2]; //ответ от устройства
  7.             firstRegister -= shift; //адресс первого регистра в соответствии со сдвигом
  8.  
  9.             //Формирую запрос
  10.             identifierTranzaction++;
  11.             //идентификатор транзакции
  12.             dataSend[0] = BitConverter.GetBytes(identifierTranzaction)[1];
  13.             dataSend[1] = BitConverter.GetBytes(identifierTranzaction)[0];
  14.             //идентификатор протокола
  15.             dataSend[2] = 0;
  16.             dataSend[3] = 0;
  17.             //длина сообщения
  18.             dataSend[4] = 0;
  19.             dataSend[5] = 6;
  20.             //адрес устройства
  21.             dataSend[6] = modbusStation;
  22.             //функция
  23.             dataSend[7] = 3;
  24.             //адрес первого регистра
  25.             dataSend[8] = BitConverter.GetBytes(firstRegister)[1];
  26.             dataSend[9] = BitConverter.GetBytes(firstRegister)[0];
  27.             //количество необходимых регистров
  28.             dataSend[10] = BitConverter.GetBytes(amountRegisters)[1];
  29.             dataSend[11] = BitConverter.GetBytes(amountRegisters)[0];
  30.  
  31.             Socket.Send(dataSend);
  32.             Socket.Receive(dataReceive);
  33.  
  34.             ushort[] dataUshort = new ushort[amountRegisters];
  35.             for (int i = 0; i < amountRegisters; i++)
  36.             {
  37.                 byte[] byteTemp = new byte[2] { dataReceive[i * 2 + (byteOrder ? 10 : 9)], dataReceive[i * 2 + (byteOrder ? 9 : 10)] };
  38.                 dataUshort[i] = BitConverter.ToUInt16(byteTemp, 0);
  39.             }
  40.  
  41.         }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

14   голосов , оценка 4.071 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы