Form1.cs 22KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Data.OleDb;
  6. using System.Drawing;
  7. using System.IO;
  8. using System.Linq;
  9. using System.Runtime.Serialization.Json;
  10. using System.Text;
  11. using System.Text.RegularExpressions;
  12. using System.Threading;
  13. using System.Threading.Tasks;
  14. using System.Windows.Forms;
  15. using GWSocketClient.db;
  16. using GWSocketClient.model;
  17. using GWSocketClient.util;
  18. using GWSocketClient.xml;
  19. using Newtonsoft.Json;
  20. using Newtonsoft.Json.Linq;
  21. using XuanJiSocket;
  22. namespace GWSocketClient
  23. {
  24. delegate void ThreadFormDelegate(object msg);
  25. public partial class Form1 : Form
  26. {
  27. #region 属性定义
  28. private string ip;
  29. private string port;
  30. private SocketHelper.TcpClients sockeTcpClients;
  31. private VcarecityPD vcarecityProtocolBean = null;
  32. private ThreadFormDelegate uiDelegate;
  33. #endregion
  34. #region Form 事件
  35. public Form1()
  36. {
  37. InitializeComponent();
  38. }
  39. private void Form1_Load(object sender, EventArgs e)
  40. {
  41. XmlLoader xmlLoader = new XmlLoader();
  42. vcarecityProtocolBean = xmlLoader.loadXml();
  43. if (vcarecityProtocolBean != null)
  44. {
  45. this.Text = vcarecityProtocolBean.ProtocolName + " - " + vcarecityProtocolBean.ProtocolNo + " - " +
  46. vcarecityProtocolBean.ProtocolStartSymbol;
  47. }
  48. SocketHelper.pushSockets = new SocketHelper.PushSockets(receiveData); //注册推送器
  49. sockeTcpClients = new SocketHelper.TcpClients();
  50. ip = tbIpaddress.Text.Trim();
  51. port = tbPort.Text.Trim();
  52. uiDelegate = addToListboxItem;
  53. timerHeartBeat.Enabled = ToolStripMenuItemHbStart.Checked;
  54. }
  55. private void Form1_FormClosing(object sender, FormClosingEventArgs e)
  56. {
  57. timerHeartBeat.Enabled = false;
  58. try
  59. {
  60. sockeTcpClients.Stop();
  61. }
  62. catch (Exception exception)
  63. {
  64. }
  65. finally
  66. {
  67. sockeTcpClients = null;
  68. }
  69. AccsessDbLoader.getInstance().closeConnection();
  70. }
  71. #endregion
  72. #region 点击事件
  73. private void btnLogin_Click(object sender, EventArgs e)
  74. {
  75. try
  76. {
  77. if (!showTopForNoLoadXML())
  78. return;
  79. ip = tbIpaddress.Text.Trim();
  80. port = tbPort.Text.Trim();
  81. sockeTcpClients.InitSocket(ip, int.Parse(port));
  82. sockeTcpClients.Start();
  83. }
  84. catch (Exception ex)
  85. {
  86. // statuslist.Items.Add(string.Format("连接失败!原因:{0}", ex.Message
  87. Console.WriteLine(ex.Message);
  88. }
  89. }
  90. private void btnQuickLogout_Click(object sender, EventArgs e)
  91. {
  92. try
  93. {
  94. sockeTcpClients.Stop();
  95. }
  96. catch (Exception exception)
  97. {
  98. addToListboxItem("你还没有登录!!" + exception.Message);
  99. }
  100. }
  101. private void tsmiLoadXml_Click(object sender, EventArgs e)
  102. {
  103. OpenFileDialog ofd = new OpenFileDialog();
  104. ofd.Filter = "XML文件|*.xml|所有文件|*.*";
  105. ofd.InitialDirectory = Application.StartupPath;
  106. if (ofd.ShowDialog() == DialogResult.OK)
  107. {
  108. string xmlFilepath = ofd.FileName;
  109. vcarecityProtocolBean = new XmlLoader().load(xmlFilepath).getVcarecityPD();
  110. this.Text = vcarecityProtocolBean.ProtocolName + " - " + vcarecityProtocolBean.ProtocolNo + " - " +
  111. vcarecityProtocolBean.ProtocolStartSymbol;
  112. }
  113. }
  114. private void btnSendData_Click(object sender, EventArgs e)
  115. {
  116. string trim = tfTmpSendData.Text.Trim();
  117. trim = trim.Replace("\n", "").Replace("\r", "").Replace("\t", "").Replace(" ", "").Replace("-", "");
  118. if (!trim.Equals(""))
  119. {
  120. byte[] ts = HexUtil.hexToBytes(trim);
  121. addToListboxItem(string.Format("发送到服务端:[{0}]", trim));
  122. sockeTcpClients.SendData(ts);
  123. }
  124. }
  125. /// <summary>
  126. /// 压力测试
  127. /// </summary>
  128. private void btnPressureTest_Click(object sender, EventArgs e)
  129. {
  130. ip = tbIpaddress.Text.Trim();
  131. port = tbPort.Text.Trim();
  132. int count = int.Parse(tbPresureTestCount.Text);
  133. ThreadPool.QueueUserWorkItem(o =>
  134. {
  135. for (int i = 1024; i < 1024 + count; i++)
  136. {
  137. SocketHelper.TcpClients clientx = new SocketHelper.TcpClients(); //初始化类库
  138. clientx.InitSocket(ip, int.Parse(port));
  139. clientx.Start();
  140. string loginCmd = "7e7e7e";
  141. loginCmd += "4442832e" + i;
  142. loginCmd += "820014383938363032423131393135353034373938" + i;
  143. loginCmd = Utils.calcCrcCode(loginCmd);
  144. sockeTcpClients.SendData(HexUtil.hexToBytes(loginCmd));
  145. Thread.Sleep(200);
  146. }
  147. });
  148. }
  149. private void buttonCmdManager_Click(object sender, EventArgs e)
  150. {
  151. InfoEditor ie = new InfoEditor();
  152. ie.ShowDialog();
  153. }
  154. private void btnTextCmd_Click(object sender, EventArgs e)
  155. {
  156. //beta test tool
  157. if (tfTmpSendData.Text.Trim().ToLower().Equals("pre"))
  158. {
  159. btnPressureTest.Visible = !btnPressureTest.Visible;
  160. tbPresureTestCount.Visible = !tbPresureTestCount.Visible;
  161. label4.Visible = !label4.Visible;
  162. }
  163. }
  164. private void toolStripMenuItemHBtime_Click(object sender, EventArgs e)
  165. {
  166. InputDialog id = new InputDialog();
  167. id.InputResult += (string topmost) =>
  168. {
  169. timerHeartBeat.Interval = int.Parse(topmost) * 1000;
  170. //5秒
  171. toolStripStatusLabelHbShow.Text = "心跳时间: " + topmost + "秒";
  172. };
  173. id.ShowDialog();
  174. }
  175. private void Id_InputResult(string topmost)
  176. {
  177. throw new NotImplementedException();
  178. }
  179. #endregion
  180. #region 处理心跳相关的
  181. private void timerHeartBeat_Tick(object sender, EventArgs e)
  182. {
  183. Thread thread = new Thread(heartBeatThread);
  184. thread.Start(this);
  185. }
  186. /*
  187. //开启心跳连接
  188. private void startHeartBeatThread()
  189. {
  190. }*/
  191. private void heartBeatThread(object o)
  192. {
  193. string hbCmd = vcarecityProtocolBean.ProtocolStartSymbol;
  194. hbCmd += tbEquipmentAddress.Text.Trim() + "840000";
  195. hbCmd = Utils.calcCrcCode(hbCmd);
  196. byte[] ts = HexUtil.hexToBytes(hbCmd);
  197. sockeTcpClients.SendData(ts);
  198. if (ToolStripMenuItemLogHb.Checked)
  199. {
  200. this.Invoke(this.uiDelegate, new object[] {string.Format("发送到服务端-心跳:[{0}]", hbCmd)});
  201. }
  202. }
  203. private void ToolStripMenuItemHbStart_CheckStateChanged(object sender, EventArgs e)
  204. {
  205. timerHeartBeat.Enabled = ToolStripMenuItemHbStart.Checked;
  206. }
  207. #endregion
  208. private bool showTopForNoLoadXML()
  209. {
  210. if (vcarecityProtocolBean == null)
  211. {
  212. MessageBox.Show("请先加载XML协议文件");
  213. return false;
  214. }
  215. return true;
  216. }
  217. private void receiveData(SocketHelper.Sockets sks)
  218. {
  219. this.Invoke(new ThreadStart(delegate
  220. {
  221. if (sks.ex != null)
  222. {
  223. switch (sks.ErrorCode)
  224. {
  225. case SocketHelper.Sockets.ErrorCodes.objectNull:
  226. addToListboxItem("状态信息:服务器连接已断开");
  227. checkLogin(false);
  228. break;
  229. case SocketHelper.Sockets.ErrorCodes.ConnectError:
  230. //连接不成功
  231. addToListboxItem("状态信息:连接服务器失败,可能是服务器未开启!");
  232. checkLogin(false);
  233. break;
  234. case SocketHelper.Sockets.ErrorCodes.ConnectSuccess:
  235. //连接成功
  236. addToListboxItem("状态信息:与服务器连接成功");
  237. addToListboxItem(string.Format("客户端信息{0}", sks.ex));
  238. sendLoginCmd();
  239. checkLogin(true);
  240. if (StripMenuItemLoSucHb.Checked)
  241. {
  242. ToolStripMenuItemHbStart.Checked = true;
  243. }
  244. break;
  245. case SocketHelper.Sockets.ErrorCodes.TrySendData:
  246. addToListboxItem("状态信息:ErrorCodes");
  247. checkLogin(false);
  248. break;
  249. default:
  250. addToListboxItem(string.Format("客户端信息{0}", sks.ex));
  251. break;
  252. }
  253. }
  254. else
  255. {
  256. byte[] buffer = new byte[sks.Offset];
  257. Array.Copy(sks.RecBuffer, buffer, sks.Offset);
  258. string byteToHexStr = HexUtil.byteToHexStr(buffer);
  259. if (!byteToHexStr.Equals(""))
  260. {
  261. handleResponse(sks, byteToHexStr);
  262. }
  263. else
  264. {
  265. addToListboxItem("状态信息:服务端主动关闭! position");
  266. sockeTcpClients.Stop();
  267. }
  268. // listBoxShow.Text += "\r\n";
  269. // listBoxShow.Text += string.Format("服务端{0}发来消息:{1}", sks.Ip, byteToHexStr);
  270. }
  271. }));
  272. }
  273. /// <summary>
  274. /// 处理回复信息
  275. /// </summary>
  276. /// <param name="sks">Socket对象</param>
  277. /// <param name="reqData">服务器发过来的信息</param>
  278. private void handleResponse(SocketHelper.Sockets sks, string reqData)
  279. {
  280. //取出原数据功能码
  281. string functionWord = reqData.Substring(18, 2);
  282. int funcode = Utils.hexToTen(functionWord);
  283. //处理心跳的回复
  284. if (funcode == 4)
  285. {
  286. string hbLen = reqData.Substring(20, 4);
  287. if (ToolStripMenuItemLogHb.Checked && hbLen.Equals("0000"))
  288. {
  289. addToListboxItem(string.Format("收到服务端{0}发来心跳funCode={2}:[{1}]", sks.Ip, reqData,reqData.Substring(18,2)));
  290. }
  291. }
  292. else
  293. {
  294. addToListboxItem(string.Format("收到服务端{0}发来消息,funCode={2}:[{1}]", sks.Ip, reqData,reqData.Substring(18,2)));
  295. }
  296. if (!(funcode == 16 || funcode == 32))
  297. {
  298. Console.WriteLine("功能码10进制=" + funcode + ",所以不用回复! data=" + reqData);
  299. return;
  300. }
  301. //16 表示要读数据,返回数据库中的数据
  302. //32 表示返回结果 成功:00 失败:01
  303. //数据长度
  304. int dataLen = Utils.hexToTen(reqData.Substring(20, 4)) * 2;
  305. string readlData = "";
  306. try
  307. {
  308. readlData = reqData.Substring(24, dataLen);
  309. }
  310. catch (Exception e)
  311. {
  312. Console.WriteLine(e.Message);
  313. addToListboxItem("数据长度与帧长度对不上!! 帧数据长度=" + (dataLen / 2) + " ,Error=" + e.Message);
  314. return;
  315. }
  316. //消息流水&测量点
  317. string flowPoint = readlData.Substring(0, 6);
  318. //ID
  319. string myId = readlData.Substring(6, 4);
  320. //对应信息
  321. string idInfo = readlData.Substring(10);
  322. //回复功能码
  323. int responceFunCode = funcode + 128;
  324. string cmd = reqData.Substring(0, 18); //前面的
  325. cmd += Utils.stringWith0(Utils.tenToHex(responceFunCode), 2); //回复功能码
  326. string body = flowPoint + myId;
  327. if (funcode == 32)
  328. {
  329. //设置数据
  330. int res = AccsessDbLoader.getInstance().setReceiveData(myId, idInfo);
  331. //成功回复00 失败回复01
  332. if (res > 0)
  333. {
  334. addToListboxItem("设置成功,功能码(10)=" + funcode + " ; ID=" + myId + " ; Value=" + idInfo);
  335. body += "00";
  336. AccsessDbLoader.getInstance().reloadAccessDb();
  337. }
  338. else
  339. {
  340. addToListboxItem("设置失败,功能码(10)=" + funcode + " ; ID=" + myId + " ; Value=" + idInfo);
  341. body += "01";
  342. }
  343. }
  344. else
  345. {
  346. //返回数据库的数据 OR 临时数据,如果临时数据有数据的话
  347. try
  348. {
  349. string responce = AccsessDbLoader.getInstance().getUserIdInfo()[myId];
  350. if (!tfTmpResponse.Text.Trim().Equals(""))
  351. {
  352. string inputRespocse = tfTmpResponse.Text.Trim();
  353. responce = Utils.stringWith0(inputRespocse, responce.Length);
  354. }
  355. addToListboxItem("读取数据,功能码(10)=" + funcode + " ; ID=" + myId + " ; 回 复=" + responce);
  356. body += responce;
  357. }
  358. catch (Exception e)
  359. {
  360. Console.WriteLine(e);
  361. addToListboxItem("异常,没有这个ID=(" + myId + "),ERROR=" + e.Message);
  362. return;
  363. }
  364. }
  365. cmd += Utils.stringWith0(Utils.tenToHex(body.Length / 2), 4); //长度
  366. cmd += body; //消息体
  367. cmd = Utils.calcCrcCode(cmd); //计算检验码
  368. addToListboxItem(string.Format("回复服务端{0}回应消息:[{1}]", sks.Ip, cmd));
  369. byte[] ts = HexUtil.hexToBytes(cmd);
  370. sockeTcpClients.SendData(ts);
  371. }
  372. private void tbEquipmentAddress_TextChanged(object sender, EventArgs e)
  373. {
  374. string equipmentAddress = tbEquipmentAddress.Text.Trim();
  375. tsslEquipmentAddress.Text = equipmentAddress.Length / 2.0 + "";
  376. }
  377. private void sendLoginCmd()
  378. {
  379. // string loginCmd = "7e7e7e4442832e833c8200143839383630324231313931353530343739383737f7";
  380. string loginCmd = vcarecityProtocolBean.ProtocolStartSymbol;
  381. loginCmd += tbEquipmentAddress.Text.Trim() + "82";
  382. if(cbCCIDIsSource.Checked)
  383. {
  384. loginCmd += Utils.stringWith0(Utils.tenToHex(tbCCID.Text.Trim().Length ), 4);
  385. loginCmd += Utils.transateCCID(tbCCID.Text.Trim());
  386. }
  387. else
  388. {
  389. loginCmd += Utils.stringWith0(Utils.tenToHex(tbCCID.Text.Trim().Length / 2), 4);
  390. loginCmd += tbCCID.Text.Trim();
  391. }
  392. loginCmd = Utils.calcCrcCode(loginCmd);
  393. //发送登录命令
  394. byte[] ts = HexUtil.hexToBytes(loginCmd);
  395. addToListboxItem(string.Format("发送到服务端,funCode={0} : [{1}]", loginCmd.Substring(18, 2), loginCmd));
  396. sockeTcpClients.SendData(ts);
  397. }
  398. private void tbCCID_TextChanged(object sender, EventArgs e)
  399. {
  400. string ccid = tbCCID.Text.Trim();
  401. tsslCCIDLEN.Text = ccid.Length / 2.0 + "";
  402. }
  403. #region ListBox相关
  404. /// <summary>
  405. /// ListBox右键菜单-点击复制
  406. /// </summary>
  407. /// <param name="sender"></param>
  408. /// <param name="e"></param>
  409. private void rightMenuCopyCmd_Click(object sender, EventArgs e)
  410. {
  411. int index = listBoxShow.SelectedIndex;
  412. if (index >= 0 && index < listBoxShow.Items.Count)
  413. {
  414. string info = listBoxShow.SelectedItem.ToString();
  415. if (!info.Equals(""))
  416. {
  417. if (info.Contains("[") || info.Contains("]"))
  418. {
  419. Regex reg = new Regex(@"\[\w+\]"); //注意里面的引号 要用双引号表示,而不是用反斜
  420. Match match = reg.Match(info);
  421. string ifs = match.ToString();
  422. ifs = ifs.Replace("[", "").Replace("]", "");
  423. if (!info.Equals(""))
  424. {
  425. Clipboard.SetDataObject(ifs);
  426. }
  427. else
  428. {
  429. Clipboard.SetDataObject(info);
  430. }
  431. }
  432. else
  433. {
  434. Clipboard.SetDataObject(info);
  435. }
  436. }
  437. }
  438. }
  439. private void addToListboxItem(object info)
  440. {
  441. if (listBoxShow.Items.Count > 1000)
  442. {
  443. listBoxShow.Items.Remove(0);
  444. // listBoxShow.Items.Clear();
  445. }
  446. Console.WriteLine(info);
  447. listBoxShow.Items.Add(info);
  448. listBoxShow.TopIndex = listBoxShow.Items.Count - 1;
  449. }
  450. private void rightMenuClearInfo_Click(object sender, EventArgs e)
  451. {
  452. listBoxShow.Items.Clear();
  453. }
  454. private void listBoxShow_DrawItem(object sender, DrawItemEventArgs e)
  455. {
  456. if (e.Index >= 0 && e.Index < listBoxShow.Items.Count)
  457. {
  458. e.DrawBackground();
  459. //
  460. string res = listBoxShow.Items[e.Index].ToString().ToLower();
  461. if (res.Contains("收到服务端"))
  462. {
  463. Font f = new Font("微软雅黑", e.Font.Size, FontStyle.Bold);
  464. e.Graphics.DrawString(((ListBox) sender).Items[e.Index].ToString(), f, new SolidBrush(Color.Blue),
  465. e.Bounds);
  466. }
  467. else if (res.Contains("发送到服务端") || res.Contains("回复"))
  468. {
  469. Font f = new Font("微软雅黑", e.Font.Size, FontStyle.Italic);
  470. e.Graphics.DrawString(((ListBox) sender).Items[e.Index].ToString(), f,
  471. new SolidBrush(Color.BlueViolet),
  472. e.Bounds);
  473. }
  474. else if (res.Contains("读取数据,") || res.Contains("设置失败,") || res.Contains("设置成功,"))
  475. {
  476. e.Graphics.DrawString(((ListBox) sender).Items[e.Index].ToString(), e.Font,
  477. new SolidBrush(Color.Red),
  478. e.Bounds);
  479. }
  480. else
  481. {
  482. e.Graphics.DrawString(((ListBox) sender).Items[e.Index].ToString(), e.Font,
  483. new SolidBrush(e.ForeColor),
  484. e.Bounds);
  485. }
  486. e.DrawFocusRectangle();
  487. }
  488. }
  489. private void listBoxShow_DoubleClick(object sender, EventArgs e)
  490. {
  491. int index = listBoxShow.SelectedIndex;
  492. if (index >= 0 && index < listBoxShow.Items.Count)
  493. {
  494. string info = listBoxShow.SelectedItem.ToString();
  495. if (!info.Equals(""))
  496. {
  497. if (info.Contains("[") || info.Contains("]"))
  498. {
  499. Regex reg = new Regex(@"\[\w+\]"); //注意里面的引号 要用双引号表示,而不是用反斜
  500. Match match = reg.Match(info);
  501. string ifs = match.ToString();
  502. ifs = ifs.Replace("[", "").Replace("]", "");
  503. if (!info.Equals(""))
  504. {
  505. // MessageBox.Show(ifs);
  506. AnaProtocol ap = new AnaProtocol(ifs);
  507. ap.ShowDialog();
  508. }
  509. }
  510. }
  511. }
  512. }
  513. #endregion
  514. #region 检验工具类
  515. private void toolStripTextBoxHbtime_KeyPress(object sender, KeyPressEventArgs e)
  516. {
  517. if (e.KeyChar != 8 && !Char.IsDigit(e.KeyChar))
  518. {
  519. e.Handled = true;
  520. }
  521. }
  522. private void checkLogin(bool isLogin)
  523. {
  524. if (isLogin)
  525. {
  526. btnLogin.Enabled = false;
  527. btnQuickLogout.Enabled = true;
  528. btnSendData.Enabled = true;
  529. ToolStripMenuItemHbStart.Enabled = true; //开启心中的点击选项
  530. if (StripMenuItemLoSucHb.Checked)
  531. {
  532. //如果勾选了登录成功并心跳
  533. timerHeartBeat.Enabled = true;
  534. }
  535. }
  536. else
  537. {
  538. btnLogin.Enabled = true;
  539. btnQuickLogout.Enabled = false;
  540. btnSendData.Enabled = false;
  541. ToolStripMenuItemHbStart.Checked = false;
  542. ToolStripMenuItemHbStart.Enabled = false;
  543. timerHeartBeat.Enabled = false;
  544. }
  545. }
  546. #endregion
  547. }
  548. }