IncvanceSendMessClass.cs 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Linq;
  5. using System.Runtime.InteropServices;
  6. using System.Text;
  7. using System.Text.RegularExpressions;
  8. using System.Threading.Tasks;
  9. using static CCDCount.DLL.Inovance.IncvanceEip;
  10. namespace CCDCount.DLL.Inovance
  11. {
  12. public class IncvanceSendMessClass
  13. {
  14. bool isStart = false;
  15. string strClaimedIP = "";
  16. int InstanceId = -1;
  17. public int OpenEip(string IP)
  18. {
  19. int result = -1;
  20. //limit input of controller
  21. bool blnTest = false;
  22. bool bValidIP = true;
  23. Regex regex = new Regex("^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$");
  24. blnTest = regex.IsMatch(IP);
  25. //输入的IP是否符合IP格式
  26. if (blnTest == true)
  27. {
  28. string[] strTemp = IP.Split(new char[] { '.' });
  29. if (strTemp.Length < 4)
  30. {
  31. Console.WriteLine("IncvanceSendMessClass-OpenEip:不符合IP格式");
  32. bValidIP = false;
  33. result = 1;
  34. }
  35. for (int i = 0; (i < strTemp.Length) && bValidIP; i++)
  36. {
  37. if (Convert.ToInt32(strTemp[i]) > 255)
  38. { //大于255则提示,不符合IP格式
  39. Console.WriteLine("IncvanceSendMessClass-OpenEip:不符合IP格式");
  40. bValidIP = false;
  41. result = 1;
  42. }
  43. }
  44. }
  45. else
  46. {
  47. //输入非数字则提示,不符合IP格式
  48. Console.WriteLine("IncvanceSendMessClass-OpenEip:不符合IP格式");
  49. bValidIP = false;
  50. result = 1;
  51. }
  52. //开启EIP协议栈
  53. if (bValidIP)
  54. {
  55. if (!isStart)
  56. {
  57. if (IncvanceEip.EipStartExt(IP, 0))
  58. {
  59. isStart = true;
  60. strClaimedIP = IP;
  61. Console.WriteLine("IncvanceSendMessClass-OpenEip:EIP协议栈开启成功");
  62. result = 0;
  63. }
  64. else
  65. {
  66. isStart = false;
  67. Console.WriteLine("IncvanceSendMessClass-OpenEip:EIP协议栈开启失败");
  68. result = 2;
  69. }
  70. return result;
  71. }
  72. else
  73. {
  74. if (string.Compare(strClaimedIP, IP) != 0)
  75. {
  76. Console.WriteLine("IncvanceSendMessClass-OpenEip:更改上位机IP时需先关闭协议栈,再开启");
  77. result = 3;
  78. return result;
  79. }
  80. else
  81. {
  82. result = 4;
  83. Console.WriteLine("IncvanceSendMessClass-OpenEip:EIP协议栈已经开启");
  84. result = 0;
  85. return result;
  86. }
  87. }
  88. }
  89. return result;
  90. }
  91. public void CloseEip()
  92. {
  93. if (isStart)
  94. {
  95. IncvanceEip.EipStop();
  96. isStart = false;
  97. Console.WriteLine("IncvanceSendMessClass-CloseEip:EIP协议栈关闭");
  98. return;
  99. }
  100. else
  101. {
  102. Console.WriteLine("IncvanceSendMessClass-CloseEip:EIP协议栈未开启,请先开启");
  103. return;
  104. }
  105. }
  106. public int CreateClass3Connect(string PLCIP)
  107. {
  108. bool blnTest = false;
  109. bool bValidIP = true;
  110. Regex regex = new Regex("^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$");
  111. blnTest = regex.IsMatch(PLCIP);
  112. if (blnTest == true)
  113. {
  114. string[] strTemp = PLCIP.Split(new char[] { '.' });
  115. for (int i = 0; i < strTemp.Length; i++)
  116. {
  117. if (Convert.ToInt32(strTemp[i]) > 255)
  118. {
  119. Console.WriteLine("IncvanceSendMessClass-CreateClass3Connect:不符合IP格式"); //大于255
  120. bValidIP = false;
  121. }
  122. }
  123. }
  124. else
  125. {
  126. Console.WriteLine("IncvanceSendMessClass-CreateClass3Connect:不符合IP格式"); //输入非数字
  127. bValidIP = false;
  128. }
  129. if (bValidIP)
  130. {
  131. int instanceId = 0;
  132. ERROR_NO errorNo;
  133. unsafe
  134. {
  135. errorNo = (ERROR_NO)EipOpenConnection(PLCIP, (IntPtr)(&instanceId));
  136. }
  137. string str = "";
  138. str += "\n请求创建连接 ip:";
  139. str += PLCIP;
  140. str += " ";
  141. if (errorNo != ERROR_NO.SUCCESS)
  142. {
  143. str += ("失败 ");
  144. switch (errorNo)
  145. {
  146. case ERROR_NO.ERR_EIP_STOPED:
  147. str += ("协议栈未开启");
  148. break;
  149. case ERROR_NO.ERRI_INVALID_CONNECTION_INSTANCE_SPECIFIED:
  150. str += ("连接的实例ID与已有的ID重复或超过最大值");
  151. break;
  152. case ERROR_NO.ERRI_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:
  153. str += ("连接的网络路径格式错误,无法检测出来目标IP离线等错误");
  154. break;
  155. case ERROR_NO.ERRI_CONNECTION_COUNT_LIMIT_REACHED:
  156. str += ("达到最大连接数量");
  157. break;
  158. case ERROR_NO.ERRI_OUT_OF_MEMORY:
  159. str += ("内存溢出,缓冲区已满");
  160. break;
  161. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:
  162. str += ("连接的网络地址无效");
  163. break;
  164. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_NO_RESPONSE:
  165. str += ("连接无响应");
  166. break;
  167. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_ERROR_RESPONSE:
  168. str += ("连接响应错误");
  169. break;
  170. default:
  171. str += ("其他错误");
  172. break;
  173. }
  174. }
  175. else
  176. {
  177. str += "成功";
  178. str += " 分配的实例ID 为 ";
  179. str += instanceId.ToString();
  180. InstanceId = instanceId;
  181. }
  182. str += "\n";
  183. Console.WriteLine("IncvanceSendMessClass-CreateClass3Connect:{0}", str);
  184. return 0;
  185. }
  186. return -1;
  187. }
  188. public void CloseClass3Connect()
  189. {
  190. if (InstanceId != -1)
  191. {
  192. ERROR_NO errorNo = (ERROR_NO)EipCloseConnection(InstanceId);
  193. string str = "";
  194. str += "\n请求关闭连接 实例ID:";
  195. str += InstanceId.ToString();
  196. if (errorNo != ERROR_NO.SUCCESS)
  197. {
  198. str += "失败";
  199. }
  200. else
  201. {
  202. str += "成功";
  203. }
  204. str += "\n";
  205. Console.WriteLine("IncvanceSendMessClass-CloseClass3Connect:{0}", str);
  206. }
  207. else
  208. {
  209. Console.WriteLine("IncvanceSendMessClass-CloseClass3Connect:参数错误");
  210. }
  211. }
  212. public void GetConnectState()
  213. {
  214. if (InstanceId != -1)
  215. {
  216. EtIPConnectionState state = (EtIPConnectionState)EipGetConnectionState(InstanceId);
  217. string str = "";
  218. str += "\n获取连接状态 实例ID:\n";
  219. str += InstanceId.ToString();
  220. switch (state)
  221. {
  222. case EtIPConnectionState.ConnectionNonExistent:
  223. str += "该实例未有连接";
  224. break;
  225. case EtIPConnectionState.ConnectionConfiguring:
  226. str += "连接正在打开过程中";
  227. break;
  228. case EtIPConnectionState.ConnectionEstablished:
  229. str += "连接已成功建立并在活动中";
  230. break;
  231. case EtIPConnectionState.ConnectionTimedOut:
  232. str += "连接超时";
  233. break;
  234. case EtIPConnectionState.ConnectionClosing:
  235. str += "连接正在关闭中";
  236. break;
  237. default:
  238. break;
  239. }
  240. str += "\n";
  241. Console.WriteLine("IncvanceSendMessClass-GetConnectState:{0}", str);
  242. }
  243. else
  244. {
  245. Console.WriteLine("IncvanceSendMessClass-GetConnectState:参数错误");
  246. }
  247. }
  248. public byte[] ReadRequest(string TagName,int ElementCount)
  249. {
  250. byte[] result = null;
  251. if (InstanceId != -1)
  252. {
  253. byte[] tagNameUTF8 = Encoding.UTF8.GetBytes(TagName);
  254. if (tagNameUTF8.Length > 255)
  255. {
  256. string str = "\n标签名长度超过255字节,请重新输入\n";
  257. //richTextBox1.AppendText(str);
  258. return result;
  259. }
  260. if (ElementCount > 0)
  261. {
  262. int destLength = 1400;
  263. byte[] dest = new byte[destLength];
  264. char[] cChar = Encoding.ASCII.GetChars(dest);
  265. tagTagReadDataBase[] pTaglist = new tagTagReadDataBase[1];
  266. pTaglist[0].pName = TagName;
  267. pTaglist[0].nElementCount = ElementCount;
  268. tagTagRetValue[] tagValue = new tagTagRetValue[1];
  269. ERROR_NO errorNo = ERROR_NO.OTHER_ERROR;
  270. //Stopwatch stopwatch = Stopwatch.StartNew();
  271. unsafe
  272. {
  273. errorNo = EipReadTagExt2(InstanceId, pTaglist, ref tagValue[0]);
  274. }
  275. //stopwatch.Stop();
  276. //Console.WriteLine("读取数据耗时:" + stopwatch.ElapsedMilliseconds);
  277. string strLog = "";
  278. strLog += "\n读取请求";
  279. if (errorNo != ERROR_NO.SUCCESS)
  280. {
  281. strLog += " 失败 标签名:" + TagName + " 实例ID:" + InstanceId.ToString() + " ";
  282. switch (errorNo)
  283. {
  284. case ERROR_NO.ERR_EIP_STOPED:
  285. strLog += ("协议栈未开启");
  286. break;
  287. case ERROR_NO.ERRI_INVALID_CONNECTION_INSTANCE_SPECIFIED:
  288. strLog += ("连接的实例ID与已有的ID重复或超过最大值");
  289. break;
  290. case ERROR_NO.ERRI_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:
  291. strLog += ("连接的网络路径格式错误,无法检测出来目标IP离线等错误");
  292. break;
  293. case ERROR_NO.ERRI_CONNECTION_COUNT_LIMIT_REACHED:
  294. strLog += ("达到最大连接数量");
  295. break;
  296. case ERROR_NO.ERRI_OUT_OF_MEMORY:
  297. strLog += ("内存溢出,缓冲区已满");
  298. break;
  299. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:
  300. strLog += ("连接的网络地址无效");
  301. break;
  302. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_NO_RESPONSE:
  303. strLog += ("连接无响应");
  304. break;
  305. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_ERROR_RESPONSE:
  306. strLog += ("连接响应错误");
  307. break;
  308. case ERROR_NO.ERRR_INVALID_DESTINATION:
  309. strLog += ("目标标签不存在");
  310. break;
  311. case ERROR_NO.ERRR_TAGNAME_TOO_LONG:
  312. strLog += ("标签名超过255字节");
  313. break;
  314. case ERROR_NO.ERRR_REQUEST_DATA_TOO_LARGE:
  315. strLog += ("请求数据超限");
  316. break;
  317. case ERROR_NO.ERRR_CONN_CONNECTION_TIMED_OUT:
  318. strLog += ("响应超时,请检查设备是否离线");
  319. break;
  320. case ERROR_NO.ERRR_TAGNAME_CONVERT_FAILED:
  321. strLog += ("标签名解析错误");
  322. break;
  323. case ERROR_NO.ERRR_SCAN_ERROR:
  324. strLog += ("扫描标签信息失败");
  325. break;
  326. default:
  327. strLog += ("其他错误");
  328. break;
  329. }
  330. strLog += "\n";
  331. //richTextBox1.AppendText(strLog);
  332. return result;
  333. }
  334. else
  335. {
  336. strLog += " 成功 实例ID:" + InstanceId.ToString() + " 数据如下:";
  337. strLog += "\n标签名:" + TagName;
  338. //richTextBox1.AppendText(strLog);
  339. string strType = "\n类型:";
  340. switch (tagValue[0].pType)
  341. {
  342. case TAG_TYPE.TAG_TYPE_BOOL:
  343. strType += "BOOL";
  344. break;
  345. case TAG_TYPE.TAG_TYPE_SINT:
  346. strType += "SINT";
  347. break;
  348. case TAG_TYPE.TAG_TYPE_INT:
  349. strType += "INT";
  350. break;
  351. case TAG_TYPE.TAG_TYPE_DINT:
  352. strType += "DINT";
  353. break;
  354. case TAG_TYPE.TAG_TYPE_LINT:
  355. strType += "LINT";
  356. break;
  357. case TAG_TYPE.TAG_TYPE_USINT:
  358. strType += "USINT";
  359. break;
  360. case TAG_TYPE.TAG_TYPE_UINT:
  361. strType += "UINT";
  362. break;
  363. case TAG_TYPE.TAG_TYPE_UDINT:
  364. strType += "UDINT";
  365. break;
  366. case TAG_TYPE.TAG_TYPE_ULINT:
  367. strType += "ULINT";
  368. break;
  369. case TAG_TYPE.TAG_TYPE_REAL:
  370. strType += "REAL";
  371. break;
  372. case TAG_TYPE.TAG_TYPE_LREAL:
  373. strType += "LREAL";
  374. break;
  375. case TAG_TYPE.TAG_TYPE_STRING:
  376. strType += "STRING";
  377. break;
  378. case TAG_TYPE.TAG_TYPE_BYTE:
  379. strType += "BYTE";
  380. break;
  381. case TAG_TYPE.TAG_TYPE_WORD:
  382. strType += "WORD";
  383. break;
  384. case TAG_TYPE.TAG_TYPE_DWORD:
  385. strType += "DWORD";
  386. break;
  387. case TAG_TYPE.TAG_TYPE_LWORD:
  388. strType += "LWORD";
  389. break;
  390. case TAG_TYPE.TAG_TYPE_STRUCT:
  391. strType += "STRUCT";
  392. break;
  393. case TAG_TYPE.TAG_TYPE_ARRAY:
  394. strType += "ARRAY";
  395. break;
  396. default:
  397. break;
  398. }
  399. //richTextBox1.AppendText(strType += "\n");
  400. string str2 = "元素个数:";
  401. str2 += ElementCount.ToString();
  402. str2 += "\n数据长度:";
  403. str2 += tagValue[0].nDataLength.ToString();
  404. //richTextBox1.AppendText(str2 += "\n");
  405. unsafe
  406. {
  407. byte* memBytePtr = (byte*)tagValue[0].pData.ToPointer();
  408. result = new byte[tagValue[0].nDataLength];
  409. for (int j = 0; j < tagValue[0].nDataLength; j++)
  410. {
  411. string str = "";
  412. str += j.ToString() + ": ";
  413. str += "0x" + String.Format("{0:X2}", memBytePtr[j]) + "\n";
  414. result[j] = memBytePtr[j];
  415. //richTextBox1.AppendText(str);
  416. }
  417. }
  418. DeleteTagListStru(ref tagValue[0], 1); //调用接口释放内存
  419. }
  420. }
  421. else
  422. {
  423. //richTextBox1.AppendText("参数错误\n");
  424. }
  425. }
  426. else
  427. {
  428. //richTextBox1.AppendText("参数错误\n");
  429. }
  430. return result;
  431. }
  432. public void WriteRequest(string TagName,int ElementCount,byte[] data)
  433. {
  434. if (InstanceId != -1)
  435. {
  436. byte[] tagNameUTF8 = Encoding.UTF8.GetBytes(TagName);
  437. if (tagNameUTF8.Length > 255)
  438. {
  439. string str = "\n标签名长度超过255字节,请重新输入\n";
  440. //richTextBox1.AppendText(str);
  441. return;
  442. }
  443. if (data.Length > 1400)
  444. {
  445. string str = "\n数据长度超过1400字节,请重新输入\n";
  446. //richTextBox1.AppendText(str);
  447. return;
  448. }
  449. if (ElementCount>0)
  450. {
  451. tagTagWriteDataBase[] pTaglist = new tagTagWriteDataBase[1];
  452. //标签1属性
  453. pTaglist[0].pName = TagName;
  454. pTaglist[0].nElementCount = ElementCount;
  455. pTaglist[0].pType = TAG_TYPE.TAG_TYPE_UNDEFINE;
  456. pTaglist[0].pData = Marshal.AllocHGlobal(1400);
  457. pTaglist[0].nDataLength = data.Length/2;
  458. byte temp = 0;
  459. for (int i = 0; i < data.Length; ++i)
  460. {
  461. temp = data[i];
  462. Marshal.WriteByte(pTaglist[0].pData + i * sizeof(byte), temp);
  463. }
  464. ERROR_NO errorNo = EipWriteTagExt2(InstanceId, pTaglist);
  465. string strLog = "";
  466. strLog += "\n写入请求 ";
  467. if (errorNo != ERROR_NO.SUCCESS)
  468. {
  469. strLog += " 失败 标签名:" + TagName + " 实例ID:" + InstanceId.ToString() + " ";
  470. switch (errorNo)
  471. {
  472. case ERROR_NO.ERR_EIP_STOPED:
  473. strLog += ("协议栈未开启");
  474. break;
  475. case ERROR_NO.ERRI_INVALID_CONNECTION_INSTANCE_SPECIFIED:
  476. strLog += ("连接的实例ID与已有的ID重复或超过最大值");
  477. break;
  478. case ERROR_NO.ERRI_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:
  479. strLog += ("连接的网络路径格式错误,无法检测出来目标IP离线等错误");
  480. break;
  481. case ERROR_NO.ERRI_CONNECTION_COUNT_LIMIT_REACHED:
  482. strLog += ("达到最大连接数量");
  483. break;
  484. case ERROR_NO.ERRI_OUT_OF_MEMORY:
  485. strLog += ("内存溢出,缓冲区已满");
  486. break;
  487. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_INVALID_NETWORK_PATH:
  488. strLog += ("连接的网络地址无效");
  489. break;
  490. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_NO_RESPONSE:
  491. strLog += ("连接无响应");
  492. break;
  493. case ERROR_NO.ERRR_CONN_CONFIG_FAILED_ERROR_RESPONSE:
  494. strLog += ("连接响应错误");
  495. break;
  496. case ERROR_NO.ERRR_INVALID_DESTINATION:
  497. strLog += ("目标标签不存在");
  498. break;
  499. case ERROR_NO.ERRR_TAGNAME_TOO_LONG:
  500. strLog += ("标签名超过255字节");
  501. break;
  502. case ERROR_NO.ERRR_REQUEST_DATA_TOO_LARGE:
  503. strLog += ("请求数据超限");
  504. break;
  505. case ERROR_NO.ERRR_CONN_CONNECTION_TIMED_OUT:
  506. strLog += ("响应超时,请检查设备是否离线");
  507. break;
  508. case ERROR_NO.ERRR_TAGNAME_CONVERT_FAILED:
  509. strLog += ("标签名解析错误");
  510. break;
  511. case ERROR_NO.ERRR_WRITE_DATASIZE_UNCONSISTENT:
  512. strLog += ("写入数据长度与标签实际长度不一致");
  513. break;
  514. case ERROR_NO.ERRR_SCAN_ERROR:
  515. strLog += ("扫描标签信息失败");
  516. break;
  517. default:
  518. strLog += ("其他错误");
  519. break;
  520. }
  521. strLog += "\n";
  522. //richTextBox1.AppendText(strLog);
  523. return;
  524. }
  525. else
  526. {
  527. strLog += "成功 实例ID:" + InstanceId.ToString() + " 写入数据如下:";
  528. strLog += "\n标签名:" + TagName;
  529. strLog += "\n元素个数:" + ElementCount.ToString();
  530. strLog += "\n写入数据长度:" + data.Length.ToString() + "\n";
  531. //richTextBox1.AppendText(strLog);
  532. for (int i = 0; i < data.Length; ++i)
  533. {
  534. string strA = "";
  535. strA += i.ToString() + ": ";
  536. strA += "0x" + String.Format("{0:X2}", data[i]) + "\n";
  537. //richTextBox1.AppendText(strA);
  538. }
  539. }
  540. }
  541. else
  542. {
  543. //richTextBox1.AppendText("参数错误\n");
  544. }
  545. }
  546. else
  547. {
  548. //richTextBox1.AppendText("参数错误\n");
  549. }
  550. }
  551. }
  552. }