ModbusTCP.cs 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867
  1. using System;
  2. using System.Threading;
  3. using System.Net.Sockets;
  4. using System.Net;
  5. using System.Net.NetworkInformation;
  6. namespace BaseLibComm
  7. {
  8. public class ModbusTcp : IDisposable
  9. {
  10. public PingReply pingReply;
  11. #region 构造函数
  12. public ModbusTcp(int _Port, string _Ip)
  13. {
  14. _ip = _Ip;
  15. _port = _Port;
  16. _online = false;
  17. Ping ping = new Ping();
  18. try
  19. {
  20. pingReply = ping.Send(_Ip);
  21. if (pingReply.Status == IPStatus.Success)
  22. {
  23. _online = true;
  24.                     // Console.WriteLine("当前在线,已ping通!");
  25.                 }
  26. else
  27. {
  28. _online = false;
  29. }
  30. }
  31. catch
  32. {
  33. }
  34. }
  35. public ModbusTcp()
  36. {
  37. }
  38. #endregion
  39. #region 共有属性
  40. public string _ip { get; set; }
  41. public int _port { get; set; }
  42. public bool _online { get; set; }
  43.         /// <summary>
  44.         /// 获取服务器是否在线
  45.         /// </summary>
  46.         public bool _conn { get; }
  47. private static Socket _SocketClient;
  48.         // private Socket clientSocket;
  49.         private Socket _socket
  50. {
  51. get
  52. {
  53. if (_SocketClient == null)
  54. {
  55. int port = _port;
  56. string host = _ip;//服务器端ip地址
  57.                     IPAddress ip = IPAddress.Parse(host);
  58. IPEndPoint ipe = new IPEndPoint(ip, port);
  59. _SocketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  60. _SocketClient.Connect(ipe);
  61. return _SocketClient;
  62. }
  63.                 //掉线重连
  64.                 if (!_SocketClient.Connected)
  65. {
  66. _SocketClient.Close();
  67. int port = _port;
  68. string host = _ip;//服务器端ip地址
  69.                     IPAddress ip = IPAddress.Parse(host);
  70. IPEndPoint ipe = new IPEndPoint(ip, port);
  71. _SocketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  72. _SocketClient.Connect(ipe);
  73. return _SocketClient;
  74. }
  75. return _SocketClient;
  76. }
  77. }
  78. #endregion
  79. #region 公有读方法
  80. /// <summary>
  81.         /// 读取线圈位状态
  82.         /// </summary>
  83.         /// <param name="_addr">MODBUS地址</param>
  84.         /// <param name="_len">读取长度</param>
  85.         /// <returns></returns>
  86. public bool[] _ReadCircle(int _addr, int _len)
  87. {
  88.             #region
  89.             /*——————————————————————————————————————————————————————————
  90.              * MODBUS_TCP---01功能码说明
  91.              * 读取多个位状态
  92.              * 发送报文:
  93.              * 00 00 00 00 00 06(此字节之后共有多少字节) 01(站号)01(功能码)61(地址高位)80(地址低位) 00(读取数量高位) 0A (读取数量低位) 
  94.              * 返回报文:
  95.              * 00 00 00 00 00 05 01 01 02(读取结果有多少个字节) 33(0---7的位寄存) 03(8---15的位寄存) 
  96.              * 读取的结果以字节存储,8位一个字节,读取10个位则需要两个字节存储状态。将字节拆分,即为单个位状态
  97.              * 关于返回值:
  98.              *    返回 bool 数组,数组的0号值为连续读取位  的首地址位状态,数组1号值为读取的第二个地址的位状态
  99.              * ——————————————————————————————————————————————————
  100.             */
  101.             #endregion
  102.             bool[] _bites = new bool[1000];
  103. if (_online)
  104. {
  105. if (_len >= 1)
  106. {
  107. int _LEN = _len * 1;
  108. byte[] _recebyte = new byte[1000];
  109. byte[] sedbyte = new byte[20];
  110. sedbyte[0] = 0x00;
  111. sedbyte[1] = 0x00;
  112. sedbyte[2] = 0x00;
  113. sedbyte[3] = 0x00;
  114. sedbyte[4] = 0x00;
  115. sedbyte[5] = 0x06;
  116. sedbyte[6] = 0x01;
  117. sedbyte[7] = 0x01;
  118. sedbyte[8] = (byte)((_addr - _addr % 256) / 256); //_addrL;//MODBUS地址低位
  119.                     sedbyte[9] = (byte)(_addr % 256); //_addrH;//modbus地址高位
  120.                     sedbyte[10] = (byte)((_len - _len % 256) / 256); //_lenL;//读取长度低位
  121.                     sedbyte[11] = (byte)(_len % 256); //_lenH;//读取长度高位
  122.                     try
  123. {
  124. _socket.Send(sedbyte, 0, 12, SocketFlags.None);//发送报文
  125. Thread.Sleep(10);
  126. int _recelen = _socket.Receive(_recebyte, 0);
  127. int _recl1 = _recebyte[5] + 6;
  128. if (_recelen == _recl1)
  129. {
  130. for (int i = 0; i < _recebyte[8]; i++)
  131. {
  132. for (int j = 0; j < 8; j++)
  133. {
  134. _bites[i * 8 + j] = (_recebyte[9 + i] & Convert.ToInt16(Math.Pow(2, j))) == Convert.ToInt16(Math.Pow(2, j));
  135. }
  136. }
  137. }
  138. }
  139. catch
  140. {
  141. }
  142. }
  143. }
  144. return _bites;
  145. }
  146. /// <summary>
  147.         /// 读取输入位状态
  148.         /// </summary>
  149.         /// <param name="_addr">MODBUS地址</param>
  150.         /// <param name="_len">读取长度</param>
  151.         /// <returns></returns>
  152.         public bool[] _ReadInput(int _addr, int _len)
  153. {
  154.             #region
  155.             /*——————————————————————————————————————————————————————————
  156.              * MODBUS_TCP---01功能码说明
  157.              * 读取多个位状态
  158.              * 发送报文:
  159.              * 00 00 00 00 00 06(此字节之后共有多少字节) 01(站号)02(功能码)61(地址高位)80(地址低位) 00(读取数量高位) 0A (读取数量低位) 
  160.              * 返回报文:
  161.              * 00 00 00 00 00 05 01 01 02(读取结果有多少个字节) 33(0---7的位寄存) 03(8---15的位寄存) 
  162.              * 读取的结果以字节存储,8位一个字节,读取10个位则需要两个字节存储状态。将字节拆分,即为单个位状态
  163.              * 关于返回值:
  164.              *    返回 bool 数组,数组的0号值为连续读取位  的首地址位状态,数组1号值为读取的第二个地址的位状态
  165.              * ——————————————————————————————————————————————————
  166.             */
  167.             #endregion
  168.             bool[] _bites = new bool[1000];
  169. if (_online)
  170. {
  171. if (_len >= 1)
  172. {
  173. int _LEN = _len * 1;
  174. byte[] _recebyte = new byte[1000];
  175. byte[] sedbyte = new byte[20];
  176. sedbyte[0] = 0x00;
  177. sedbyte[1] = 0x00;
  178. sedbyte[2] = 0x00;
  179. sedbyte[3] = 0x00;
  180. sedbyte[4] = 0x00;
  181. sedbyte[5] = 0x06;
  182. sedbyte[6] = 0x01;
  183. sedbyte[7] = 0x02;
  184. sedbyte[8] = (byte)((_addr - _addr % 256) / 256); //_addrL;//MODBUS地址低位
  185.                     sedbyte[9] = (byte)(_addr % 256); //_addrH;//modbus地址高位
  186.                     sedbyte[10] = (byte)((_len - _len % 256) / 256); //_lenL;//读取长度低位
  187.                     sedbyte[11] = (byte)(_len % 256); //_lenH;//读取长度高位
  188.                     try
  189. {
  190. _socket.Send(sedbyte, 0, 12, SocketFlags.None);//发送报文
  191. Thread.Sleep(10);
  192. int _recelen = _socket.Receive(_recebyte, 0);
  193. int _recl1 = _recebyte[5] + 6;
  194. if (_recelen == _recl1)
  195. {
  196. for (int i = 0; i < _recebyte[8]; i++)
  197. {
  198. for (int j = 0; j < 8; j++)
  199. {
  200. _bites[i * 8 + j] = (_recebyte[9 + i] & Convert.ToInt16(Math.Pow(2, j))) == Convert.ToInt16(Math.Pow(2, j));
  201. }
  202. }
  203. }
  204. }
  205. catch
  206. {
  207. }
  208. }
  209. }
  210. return _bites;
  211. }
  212. /// <summary>
  213. /// 读多个单精度浮点数
  214.         /// </summary>
  215.         /// <param name="_addr">MODBUS地址</param>
  216.         /// <param name="_len">读取长度</param>
  217.         /// <returns></returns>
  218. public float[] _ReadMultiFloat(int _addr, int _len, ref string Values)
  219. {
  220. float[] _float = new float[100];
  221. try
  222. {
  223. if (_online)
  224. {
  225. if (_len >= 1)
  226. {
  227. int _LEN = _len * 2;
  228. byte[] _recebyte = new byte[1000];
  229. byte[] sedbyte = new byte[20];
  230. sedbyte[0] = 0x00;
  231. sedbyte[1] = 0x00;
  232. sedbyte[2] = 0x00;
  233. sedbyte[3] = 0x00;
  234. sedbyte[4] = 0x00;
  235. sedbyte[5] = 0x06;
  236. sedbyte[6] = 0x01;
  237. sedbyte[7] = 0x03;
  238. sedbyte[8] = (byte)((_addr - _addr % 256) / 256); //_addrL;//MODBUS地址低位
  239. sedbyte[9] = (byte)(_addr % 256); //_addrH;//modbus地址高位
  240. sedbyte[10] = (byte)((_len - _len % 256) / 256); //_lenL;//读取长度低位
  241. sedbyte[11] = (byte)(_len % 256); //_lenH;//读取长度高位
  242.                         _socket.Send(sedbyte, 0, 12, SocketFlags.None);//发送报文
  243. Thread.Sleep(10);
  244. int _recelen = _socket.Receive(_recebyte, 0);
  245. int _s1 = _len * 4 + 9;
  246. if (_recelen == _s1)//校验返回的数据
  247.                         {
  248. byte[] _bs = new byte[4];
  249.                             //   rec = rec + 1;
  250.                             for (int i = 0; i < _len; i++)
  251. {
  252. _bs[0] = _recebyte[10 + i * 4];
  253. _bs[1] = _recebyte[9 + i * 4];
  254. _bs[2] = _recebyte[12 + i * 4];
  255. _bs[3] = _recebyte[11 + i * 4];
  256. _float[i] = BitConverter.ToSingle(_bs, 0);
  257. Values = _float[0].ToString();
  258. }
  259.                             //  MessageBox.Show("ok!");
  260.                         }
  261. }
  262. }
  263. }
  264. catch
  265. {
  266. }
  267. return _float;
  268. }
  269.         /// <summary>
  270.         /// 读多个有符号32位数据
  271.         /// </summary>
  272.         /// <param name="_addr">MODBUS地址</param>
  273.         /// <param name="_len">读取长度</param>
  274.         /// <returns></returns>
  275.         public Int32[] _ReadMultiInt32(int _addr, int _len, ref string Values)
  276. {
  277. Int32[] _int32 = new Int32[100];
  278. try
  279. {
  280. if (_online)
  281. {
  282. if (_len >= 1)
  283. {
  284. int _LEN = _len * 2;
  285. byte[] _recebyte = new byte[1000];
  286. byte[] sedbyte = new byte[20];
  287. sedbyte[0] = 0x00;
  288. sedbyte[1] = 0x00;
  289. sedbyte[2] = 0x00;
  290. sedbyte[3] = 0x00;
  291. sedbyte[4] = 0x00;
  292. sedbyte[5] = 0x06;
  293. sedbyte[6] = 0x01;
  294. sedbyte[7] = 0x03;
  295. sedbyte[8] = (byte)((_addr - _addr % 256) / 256); //_addrL;//MODBUS地址低位
  296. sedbyte[9] = (byte)(_addr % 256); //_addrH;//modbus地址高位
  297. sedbyte[10] = (byte)((_len - _len % 256) / 256); //_lenL;//读取长度低位
  298. sedbyte[11] = (byte)(_len % 256); //_lenH;//读取长度高位
  299.                         _socket.Send(sedbyte, 0, 12, SocketFlags.None);//发送报文
  300. Thread.Sleep(10);
  301. int _recelen = _socket.Receive(_recebyte, 0);
  302. int _s1 = _len * 4 + 9;
  303. if (_recelen == _s1)//校验返回的数据
  304.                         {
  305. byte[] _bs = new byte[4];
  306.                             //   rec = rec + 1;
  307.                             for (int i = 0; i < _len; i++)
  308. {
  309. _bs[0] = _recebyte[10 + i * 4];
  310. _bs[1] = _recebyte[9 + i * 4];
  311. _bs[2] = _recebyte[12 + i * 4];
  312. _bs[3] = _recebyte[11 + i * 4];
  313. _int32[i] = BitConverter.ToInt32(_bs, 0);
  314. Values = _int32[0].ToString();
  315. }
  316.                             //  MessageBox.Show("ok!");
  317.                         }
  318. }
  319. }
  320. }
  321. catch
  322. {
  323. }
  324. return _int32;
  325. }
  326.         /// <summary>
  327.         /// 读多个无符号32位数据
  328.         /// </summary>
  329.         /// <param name="_addr">MODBUS地址</param>
  330.         /// <param name="_len">读取长度</param>
  331.         /// <returns></returns>
  332.         public uint[] _ReadMultiUint32(int _addr, int _len)
  333. {
  334. uint[] _uint = new uint[100];
  335. try
  336. {
  337. if (_online)
  338. {
  339. if (_len >= 1)
  340. {
  341. int _LEN = _len * 2;
  342. byte[] _recebyte = new byte[1000];
  343. byte[] sedbyte = new byte[20];
  344. sedbyte[0] = 0x00;
  345. sedbyte[1] = 0x00;
  346. sedbyte[2] = 0x00;
  347. sedbyte[3] = 0x00;
  348. sedbyte[4] = 0x00;
  349. sedbyte[5] = 0x06;
  350. sedbyte[6] = 0x01;
  351. sedbyte[7] = 0x03;
  352. sedbyte[8] = (byte)((_addr - _addr % 256) / 256); //_addrL;//MODBUS地址低位
  353. sedbyte[9] = (byte)(_addr % 256); //_addrH;//modbus地址高位
  354. sedbyte[10] = (byte)((_len - _len % 256) / 256); //_lenL;//读取长度低位
  355. sedbyte[11] = (byte)(_len % 256); //_lenH;//读取长度高位
  356.                         _socket.Send(sedbyte, 0, 12, SocketFlags.None);//发送报文
  357. Thread.Sleep(10);
  358. int _recelen = _socket.Receive(_recebyte, 0);
  359. int _s1 = _len * 4 + 9;
  360. if (_recelen == _s1)//校验返回的数据
  361.                         {
  362. byte[] _bs = new byte[4];
  363.                             // rec = rec + 1;
  364.                             for (int i = 0; i < _len; i++)
  365. {
  366. _bs[0] = _recebyte[10 + i * 4];
  367. _bs[1] = _recebyte[9 + i * 4];
  368. _bs[2] = _recebyte[12 + i * 4];
  369. _bs[3] = _recebyte[11 + i * 4];
  370. _uint[i] = BitConverter.ToUInt32(_bs, 0);
  371. }
  372.                             //  MessageBox.Show("ok!");
  373.                         }
  374. }
  375. }
  376. }
  377. catch
  378. {
  379. }
  380. return _uint;
  381. }
  382.         /// <summary>
  383.         /// 读多个有符号16位数据
  384.         /// </summary>
  385.         /// <param name="_addr">MOFBUS地址</param>
  386.         /// <param name="_len">读取长度</param>
  387.         /// <returns></returns>
  388.         public short[] _short(int _addr, int _len)
  389. {
  390. short[] _ints = new short[1000];
  391. try
  392. {
  393. if (_online)
  394. {
  395.                     // float[] _float = new float[100];
  396.                     if (_len >= 1)
  397. {
  398. int _LEN = _len * 1;
  399. byte[] _recebyte = new byte[1000];
  400. byte[] sedbyte = new byte[20];
  401. byte[] _lengbyte = BitConverter.GetBytes(_LEN);
  402. byte[] _addrbyte = BitConverter.GetBytes(_addr);
  403. sedbyte[0] = 0x00;
  404. sedbyte[1] = 0x00;
  405. sedbyte[2] = 0x00;
  406. sedbyte[3] = 0x00;
  407. sedbyte[4] = 0x00;
  408. sedbyte[5] = 0x06;
  409. sedbyte[6] = 0x01;
  410. sedbyte[7] = 0x03;
  411. sedbyte[8] = (byte)((_addr - _addr % 256) / 256); //_addrL;//MODBUS地址低位
  412. sedbyte[9] = (byte)(_addr % 256); //_addrH;//modbus地址高位
  413. sedbyte[10] = (byte)((_len - _len % 256) / 256); //_lenL;//读取长度低位
  414. sedbyte[11] = (byte)(_len % 256); //_lenH;//读取长度高位
  415.                         _socket.Send(sedbyte, 0, 12, SocketFlags.None);//发送报文
  416. Thread.Sleep(10);
  417. int _recelen = _socket.Receive(_recebyte, 0);
  418. int _recl = _recebyte[8] + 9;
  419. if (_recelen == _recl)
  420. {
  421. for (int i = 0; i < _recebyte[8]; i++)
  422. {
  423. _ints[i] = (short)((_recebyte[9 + i * 2] << 8) | (_recebyte[10 + i * 2]));
  424. }
  425. }
  426. }
  427. }
  428. }
  429. catch
  430. {
  431. }
  432. return _ints;
  433. }
  434.         /// <summary>
  435.         /// 读多个无符号16位数据
  436.         /// </summary>
  437.         /// <param name="_addr">MODBUS地址</param>
  438.         /// <param name="_len">读取长度</param>
  439.         /// <returns></returns>
  440.         public UInt16[] _ReadMultiUint16(int _addr, int _len)
  441. {
  442. UInt16[] _ints = new UInt16[1000];
  443. try
  444. {
  445. if (_online)
  446. {
  447. if (_len >= 1)
  448. {
  449. int _LEN = _len * 1;
  450. byte[] _recebyte = new byte[1000];
  451. byte[] sedbyte = new byte[20];
  452. byte[] _lengbyte = BitConverter.GetBytes(_LEN);
  453. byte[] _addrbyte = BitConverter.GetBytes(_addr);
  454. sedbyte[0] = 0x00;
  455. sedbyte[1] = 0x00;
  456. sedbyte[2] = 0x00;
  457. sedbyte[3] = 0x00;
  458. sedbyte[4] = 0x00;
  459. sedbyte[5] = 0x06;
  460. sedbyte[6] = 0x01;
  461. sedbyte[7] = 0x03;
  462. sedbyte[8] = (byte)((_addr - _addr % 256) / 256); //_addrL;//MODBUS地址低位
  463. sedbyte[9] = (byte)(_addr % 256); //_addrH;//modbus地址高位
  464. sedbyte[10] = (byte)((_len - _len % 256) / 256); //_lenL;//读取长度低位
  465. sedbyte[11] = (byte)(_len % 256); //_lenH;//读取长度高位
  466.                         _socket.Send(sedbyte, 0, 12, SocketFlags.None);//发送报文
  467. Thread.Sleep(10);
  468. int _recelen = _socket.Receive(_recebyte, 0);
  469. int _recl = _recebyte[8] + 9;
  470. if (_recelen == _recl)
  471. {
  472. for (int i = 0; i < _recebyte[8] / 2; i++)
  473. {
  474. _ints[i] = Convert.ToUInt16(((_recebyte[9 + i * 2] << 8) | (_recebyte[10 + i * 2])));
  475. }
  476. }
  477. }
  478. }
  479. }
  480. catch
  481. {
  482. }
  483. return _ints;
  484. }
  485. #endregion
  486. #region 共有写方法
  487. /// <summary>
  488.         /// 写单个线圈
  489.         /// </summary>
  490.         /// <param name="_addr">MODBUS地址</param>
  491.         /// <param name="_bool">值:TRUE  or FALSE</param>
  492. public bool _WriteSingleCircle(int _addr, bool _bool)
  493. {
  494. bool _successful = false;
  495. try
  496. {
  497. if (_online)
  498. {
  499. byte[] _recebyte = new byte[1000];
  500. byte _bools = 0;
  501. byte[] _addrbyte = BitConverter.GetBytes(_addr);
  502. if (_bool)
  503. {
  504. _bools = 1;
  505. }
  506. byte[] sedbyte = new byte[30];
  507. sedbyte[0] = 0x00;
  508. sedbyte[1] = 0x00;
  509. sedbyte[2] = 0x00;
  510. sedbyte[3] = 0x00;
  511. sedbyte[4] = 0x00;
  512. sedbyte[5] = 0x06;
  513. sedbyte[6] = 0x01;
  514. sedbyte[7] = 0x05;
  515. sedbyte[8] = (byte)((_addr - _addr % 256) / 256); //_addrL;//MODBUS地址低位
  516. sedbyte[9] = (byte)(_addr % 256); //_addrH;//modbus地址高位
  517. sedbyte[10] = _bools;
  518. _socket.Send(sedbyte, 0, 11, SocketFlags.None);
  519. Thread.Sleep(10);
  520. int _recelen = _socket.Receive(_recebyte, 0);
  521. if (_recelen == 12)
  522. {
  523. _successful = true;
  524. }
  525. }
  526. }
  527. catch
  528. {
  529. }
  530. return _successful;
  531. }
  532.         /// <summary>
  533.         /// 写入单个无符号16位数据
  534.         /// </summary>
  535.         /// <param name="_addr">MODBUS地址</param>
  536.         /// <param name="_data">无符号16位数据</param>
  537.         /// <returns></returns>
  538.         public bool _WriteSingleUint(int _addr, UInt16 _data)
  539. {
  540. bool _successful = false;
  541. try
  542. {
  543. if (_online)
  544. {
  545. byte[] _recebyte = new byte[1000];
  546. //byte _addrH = 0;
  547. //byte _addrL = 1;
  548. byte[] sedbyte = new byte[20];
  549. byte[] _addrbyte = BitConverter.GetBytes(_addr);
  550. if (_data < 65535)
  551. {
  552. UInt16 _y = Convert.ToUInt16(_data);
  553. byte[] intBuff = BitConverter.GetBytes(_y);
  554. sedbyte[0] = 0x00;
  555. sedbyte[1] = 0x00;
  556. sedbyte[2] = 0x00;
  557. sedbyte[3] = 0x00;
  558. sedbyte[4] = 0x00;
  559. sedbyte[5] = 0x06;
  560. sedbyte[6] = 0x01;
  561. sedbyte[7] = 0x06;
  562. sedbyte[8] = (byte)((_addr - _addr % 256) / 256); //_addrL;//MODBUS地址位
  563. sedbyte[9] = (byte)(_addr % 256); //_addrH;//modbus地址高位
  564.                         sedbyte[10] = intBuff[1];
  565. sedbyte[11] = intBuff[0];
  566. _socket.Send(sedbyte, 0, 12, SocketFlags.None);//发送报文
  567. Thread.Sleep(10);
  568. int _recelen = _socket.Receive(_recebyte, 0);
  569. if (_recelen == 12)
  570. {
  571. _successful = true;
  572. }
  573. }
  574. }
  575. }
  576. catch
  577. {
  578. }
  579. return _successful;
  580. }
  581.         /// <summary>
  582.         /// 写入单个有符号16位数据
  583.         /// </summary>
  584.         /// <param name="_addr">MODBUS地址</param>
  585.         /// <param name="_data">有符号16位数据</param>
  586.         /// <returns></returns>
  587.         public bool _WriteSingleInt(int _addr, Int16 _data)
  588. {
  589. bool _successful = false;
  590. try
  591. {
  592. if (_online)
  593. {
  594. byte[] _recebyte = new byte[1000];
  595. //byte _addrH = 0;
  596. //byte _addrL = 1;
  597. byte[] sedbyte = new byte[20];
  598. byte[] _addrbyte = BitConverter.GetBytes(_addr);
  599. if (_data < 32767 || _data < -32767)
  600. {
  601. Int16 _y = Convert.ToInt16(_data);
  602. byte[] intBuff = BitConverter.GetBytes(_y);
  603. sedbyte[0] = 0x00;
  604. sedbyte[1] = 0x00;
  605. sedbyte[2] = 0x00;
  606. sedbyte[3] = 0x00;
  607. sedbyte[4] = 0x00;
  608. sedbyte[5] = 0x06;
  609. sedbyte[6] = 0x01;
  610. sedbyte[7] = 0x06;
  611. sedbyte[8] = (byte)((_addr - _addr % 256) / 256); //_addrL;//MODBUS地址位
  612. sedbyte[9] = (byte)(_addr % 256);
  613. sedbyte[10] = intBuff[1];
  614. sedbyte[11] = intBuff[0];
  615. _socket.Send(sedbyte, 0, 12, SocketFlags.None);//发送报文
  616. Thread.Sleep(10);
  617. int _recelen = _socket.Receive(_recebyte, 0);
  618. if (_recelen == 12)
  619. {
  620. _successful = true;
  621. }
  622. }
  623. }
  624. }
  625. catch
  626. {
  627. }
  628. return _successful;
  629. }
  630.         /// <summary>
  631.         /// 写入单个有符号32位数据
  632.         /// </summary>
  633.         /// <param name="_addr">MODBUS地址</param>
  634.         /// <param name="_data">数据</param>
  635.         /// <returns></returns>
  636.         public bool _WriteSingleInt32(int _addr, Int32 _data)
  637. {
  638.             //形参_data 单精度  传入实参时,实参数字后需要加f表示单精度
  639.             bool _successful = false;
  640. try
  641. {
  642. if (_online)
  643. {
  644. byte[] _recebyte = new byte[1000];
  645. byte[] sedbyte = new byte[20];
  646. byte[] _addrbyte = BitConverter.GetBytes(_addr);
  647. byte[] intBuff = BitConverter.GetBytes(_data);
  648. sedbyte[0] = 0x00;
  649. sedbyte[1] = 0x00;
  650. sedbyte[2] = 0x00;
  651. sedbyte[3] = 0x00;
  652. sedbyte[4] = 0x00;
  653. sedbyte[5] = 0x0B;
  654. sedbyte[6] = 0x01;
  655. sedbyte[7] = 0x10;
  656. sedbyte[8] = (byte)((_addr - _addr % 256) / 256); //_addrL;//MODBUS地址位
  657. sedbyte[9] = (byte)(_addr % 256);
  658. sedbyte[10] = 0x00;
  659. sedbyte[11] = 0x02;
  660. sedbyte[12] = 0x04;
  661. sedbyte[13] = intBuff[1];
  662. sedbyte[14] = intBuff[0];
  663. sedbyte[15] = intBuff[3];
  664. sedbyte[16] = intBuff[2];
  665. _socket.Send(sedbyte, 0, 17, SocketFlags.None);//发送报文
  666. Thread.Sleep(10);
  667. int _recelen = _socket.Receive(_recebyte, 0);
  668. if (_recelen == 12)
  669. {
  670. _successful = true;
  671. }
  672. }
  673. }
  674. catch
  675. {
  676. }
  677. return _successful;
  678. }
  679.         /// <summary>
  680.         /// 写入单个无符号32数据
  681.         /// </summary>
  682.         /// <param name="_addr">MODBUS地址</param>
  683.         /// <param name="_data">无符号32位数据</param>
  684.         /// <returns></returns>
  685.         public bool _WriteSingleUint32(int _addr, UInt32 _data)
  686. {
  687.             //形参_data 单精度  传入实参时,实参数字后需要加f表示单精度
  688.             bool _successful = false;
  689. try
  690. {
  691. if (_online)
  692. {
  693. byte[] _recebyte = new byte[1000];
  694. byte[] sedbyte = new byte[20];
  695. byte[] _addrbyte = BitConverter.GetBytes(_addr);
  696. byte[] intBuff = BitConverter.GetBytes(_data);
  697. sedbyte[0] = 0x00;
  698. sedbyte[1] = 0x00;
  699. sedbyte[2] = 0x00;
  700. sedbyte[3] = 0x00;
  701. sedbyte[4] = 0x00;
  702. sedbyte[5] = 0x0B;
  703. sedbyte[6] = 0x01;
  704. sedbyte[7] = 0x10;
  705. sedbyte[8] = (byte)((_addr - _addr % 256) / 256); //_addrL;//MODBUS地址位
  706. sedbyte[9] = (byte)(_addr % 256);
  707. sedbyte[10] = 0x00;
  708. sedbyte[11] = 0x02;
  709. sedbyte[12] = 0x04;
  710. sedbyte[13] = intBuff[1];
  711. sedbyte[14] = intBuff[0];
  712. sedbyte[15] = intBuff[3];
  713. sedbyte[16] = intBuff[2];
  714. _socket.Send(sedbyte, 0, 17, SocketFlags.None);//发送报文
  715. Thread.Sleep(10);
  716. int _recelen = _socket.Receive(_recebyte, 0);
  717. if (_recelen == 12)
  718. {
  719. _successful = true;
  720. }
  721. }
  722. }
  723. catch
  724. {
  725. }
  726. return _successful;
  727. }
  728.         /// <summary>
  729.         /// 单寄存器写入单精度浮点数
  730.         /// </summary>
  731.         /// <param name="_addr">MODBUS地址</param>
  732.         /// <param name="_data">单精度浮点数数据</param>
  733.         /// <returns></returns>
  734.         public bool _WriteSingleFloat(int _addr, Single _data)
  735. {
  736.             //形参_data 单精度  传入实参时,实参数字后需要加f表示单精度
  737.             bool _successful = false;
  738. try
  739. {
  740. if (_online)
  741. {
  742. byte[] _recebyte = new byte[1000];
  743. byte[] sedbyte = new byte[20];
  744. byte[] _addrbyte = BitConverter.GetBytes(_addr);
  745. byte[] intBuff = BitConverter.GetBytes(_data);
  746. sedbyte[0] = 0x00;
  747. sedbyte[1] = 0x00;
  748. sedbyte[2] = 0x00;
  749. sedbyte[3] = 0x00;
  750. sedbyte[4] = 0x00;
  751. sedbyte[5] = 0x0B;
  752. sedbyte[6] = 0x01;
  753. sedbyte[7] = 0x10;
  754. sedbyte[8] = (byte)((_addr - _addr % 256) / 256); //_addrL;//MODBUS地址位
  755. sedbyte[9] = (byte)(_addr % 256);
  756. sedbyte[10] = 0x00;
  757. sedbyte[11] = 0x02;
  758. sedbyte[12] = 0x04;
  759. sedbyte[13] = intBuff[1];
  760. sedbyte[14] = intBuff[0];
  761. sedbyte[15] = intBuff[3];
  762. sedbyte[16] = intBuff[2];
  763. _socket.Send(sedbyte, 0, 17, SocketFlags.None);//发送报文
  764. Thread.Sleep(10);
  765. int _recelen = _socket.Receive(_recebyte, 0);
  766. if (_recelen == 12)
  767. {
  768. _successful = true;
  769. }
  770. }
  771. }
  772. catch
  773. {
  774. }
  775. return _successful;
  776. }
  777. #endregion
  778. public void DisConnect()
  779. {
  780. _socket.Close();
  781. }
  782. #region IDisposable Support
  783. private bool disposedValue = false; // 要检测冗余调用
  784.         protected virtual void Dispose(bool disposing)
  785. {
  786. if (!disposedValue)
  787. {
  788. if (disposing)
  789. {
  790.                     // TODO: 释放托管状态(托管对象)。
  791.                 }
  792.                 // TODO: 释放未托管的资源(未托管的对象)并在以下内容中替代终结器。
  793.                 // TODO: 将大型字段设置为 null。
  794.                 disposedValue = true;
  795. }
  796. }
  797.         // TODO: 仅当以上 Dispose(bool disposing) 拥有用于释放未托管资源的代码时才替代终结器。
  798.         //~ModbusTcp() {
  799.         //   // 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。
  800.         //   Dispose(false);
  801.         //    }
  802.         // 添加此代码以正确实现可处置模式。
  803.         public void Dispose()
  804. {
  805.             // 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。
  806.             Dispose(true);
  807.             // TODO: 如果在以上内容中替代了终结器,则取消注释以下行。
  808.             // GC.SuppressFinalize(this);
  809.         }
  810.         #endregion
  811.     }
  812. }