|
@@ -23,6 +23,8 @@ using XuanJiSocket;
|
23
|
23
|
|
24
|
24
|
namespace GWSocketClient
|
25
|
25
|
{
|
|
26
|
+ delegate void ThreadFormDelegate(object msg);
|
|
27
|
+
|
26
|
28
|
public partial class Form1 : Form
|
27
|
29
|
{
|
28
|
30
|
public Form1()
|
|
@@ -34,9 +36,9 @@ namespace GWSocketClient
|
34
|
36
|
private string port;
|
35
|
37
|
private SocketHelper.TcpClients sockeTcpClients;
|
36
|
38
|
private VcarecityPD vcarecityProtocolBean = null;
|
|
39
|
+ private volatile bool hbRunFlag = false; //心跳线程标志
|
|
40
|
+ private ThreadFormDelegate uiDelegate;
|
37
|
41
|
|
38
|
|
- private int heartBeatInterval = 5; //Default 心跳间隔
|
39
|
|
- private bool isStartHeartbeat = true;
|
40
|
42
|
|
41
|
43
|
private void Form1_Load(object sender, EventArgs e)
|
42
|
44
|
{
|
|
@@ -52,38 +54,49 @@ namespace GWSocketClient
|
52
|
54
|
sockeTcpClients = new SocketHelper.TcpClients();
|
53
|
55
|
ip = tbIpaddress.Text.Trim();
|
54
|
56
|
port = tbPort.Text.Trim();
|
55
|
|
- isStartHeartbeat = ToolStripMenuItemHbStart.Checked;
|
|
57
|
+
|
|
58
|
+ uiDelegate = addToListboxItem;
|
56
|
59
|
}
|
57
|
60
|
|
58
|
61
|
|
59
|
62
|
#region 处理心跳相关的
|
60
|
63
|
|
61
|
|
- private void startHeartBeat()
|
|
64
|
+ //开启心跳连接
|
|
65
|
+ private void startHeartBeatThread()
|
62
|
66
|
{
|
63
|
67
|
Thread thread = new Thread(heartBeatThread);
|
64
|
|
- thread.Start();
|
65
|
|
-
|
|
68
|
+ thread.Start(this);
|
66
|
69
|
}
|
67
|
70
|
|
68
|
|
- private void heartBeatThread()
|
|
71
|
+ private void heartBeatThread(object o)
|
69
|
72
|
{
|
70
|
|
- while (isStartHeartbeat)
|
|
73
|
+ while (hbRunFlag)
|
71
|
74
|
{
|
72
|
|
- int interval = int.Parse(toolStripTextBoxHbtime.Text.Trim());
|
|
75
|
+
|
|
76
|
+ int interval = 5;
|
|
77
|
+ if (!toolStripTextBoxHbtime.Text.Trim().Equals(""))
|
|
78
|
+ {
|
|
79
|
+ interval = int.Parse(toolStripTextBoxHbtime.Text.Trim());
|
|
80
|
+ }
|
73
|
81
|
Thread.Sleep(interval * 1000);
|
74
|
|
- string hbCmd = vcarecityProtocolBean.ProtocolStartSymbol;
|
75
|
|
- hbCmd += tbEquipmentAddress.Text.Trim() + "840000";
|
76
|
|
- hbCmd = Utils.calcCrcCode(hbCmd);
|
77
|
|
- byte[] ts = HexUtil.hexToBytes(hbCmd);
|
78
|
|
- sockeTcpClients.SendData(ts);
|
79
|
82
|
|
80
|
|
- if (ToolStripMenuItemLogHb.Checked)
|
|
83
|
+
|
|
84
|
+ if (hbRunFlag)
|
81
|
85
|
{
|
82
|
|
- Console.WriteLine("发送到服务端-心跳:[{0}]", hbCmd);
|
83
|
|
- addToListboxItem(string.Format("发送到服务端-心跳:[{0}]", hbCmd));
|
|
86
|
+ string hbCmd = vcarecityProtocolBean.ProtocolStartSymbol;
|
|
87
|
+ hbCmd += tbEquipmentAddress.Text.Trim() + "840000";
|
|
88
|
+ hbCmd = Utils.calcCrcCode(hbCmd);
|
|
89
|
+ byte[] ts = HexUtil.hexToBytes(hbCmd);
|
|
90
|
+
|
|
91
|
+ sockeTcpClients.SendData(ts);
|
|
92
|
+
|
|
93
|
+ if (ToolStripMenuItemLogHb.Checked)
|
|
94
|
+ {
|
|
95
|
+ this.Invoke(this.uiDelegate, new object[] {string.Format("发送到服务端-心跳:[{0}]", hbCmd)});
|
|
96
|
+ }
|
84
|
97
|
}
|
85
|
98
|
}
|
86
|
|
- addToListboxItem("心跳线程结束!");
|
|
99
|
+ this.Invoke(this.uiDelegate, new object[] {"心跳线程结束!"});
|
87
|
100
|
}
|
88
|
101
|
|
89
|
102
|
#endregion
|
|
@@ -107,57 +120,79 @@ namespace GWSocketClient
|
107
|
120
|
switch (sks.ErrorCode)
|
108
|
121
|
{
|
109
|
122
|
case SocketHelper.Sockets.ErrorCodes.objectNull:
|
|
123
|
+ addToListboxItem("状态信息:服务器连接已断开");
|
|
124
|
+ hbRunFlag = false;
|
|
125
|
+ checkLogin(false);
|
110
|
126
|
break;
|
111
|
127
|
case SocketHelper.Sockets.ErrorCodes.ConnectError:
|
|
128
|
+ //连接不成功
|
|
129
|
+ addToListboxItem("状态信息:连接服务器失败,可能是服务器未开启!");
|
112
|
130
|
break;
|
113
|
131
|
case SocketHelper.Sockets.ErrorCodes.ConnectSuccess:
|
114
|
|
- addToListboxItem("状态信息:连接成功.!");
|
|
132
|
+ //连接成功
|
|
133
|
+ addToListboxItem("状态信息:与服务器连接成功");
|
|
134
|
+ addToListboxItem(string.Format("客户端信息{0}", sks.ex));
|
|
135
|
+ checkLogin(true);
|
|
136
|
+ sendLoginCmd();
|
|
137
|
+ hbRunFlag = true;
|
|
138
|
+ startHeartBeatThread();
|
115
|
139
|
break;
|
116
|
140
|
case SocketHelper.Sockets.ErrorCodes.TrySendData:
|
|
141
|
+ addToListboxItem("状态信息:ErrorCodes");
|
117
|
142
|
break;
|
118
|
143
|
default:
|
|
144
|
+ addToListboxItem(string.Format("客户端信息{0}", sks.ex));
|
119
|
145
|
break;
|
120
|
146
|
}
|
121
|
|
- addToListboxItem(string.Format("客户端信息{0}", sks.ex));
|
122
|
|
- //连接成功,启动心跳线程
|
123
|
|
- //startHeartBeat();
|
124
|
147
|
}
|
125
|
148
|
else
|
126
|
149
|
{
|
127
|
150
|
byte[] buffer = new byte[sks.Offset];
|
128
|
151
|
Array.Copy(sks.RecBuffer, buffer, sks.Offset);
|
129
|
152
|
string byteToHexStr = HexUtil.byteToHexStr(buffer);
|
130
|
|
- if (byteToHexStr.Equals("ServerOff"))
|
|
153
|
+
|
|
154
|
+ if (!byteToHexStr.Equals(""))
|
131
|
155
|
{
|
132
|
|
- addToListboxItem("状态信息:服务端主动关闭!");
|
|
156
|
+ handleResponse(sks, byteToHexStr);
|
133
|
157
|
}
|
134
|
158
|
else
|
135
|
159
|
{
|
136
|
|
- if (!byteToHexStr.Equals(""))
|
137
|
|
- {
|
138
|
|
- addToListboxItem(string.Format("收到服务端{0}发来消息:[{1}]", sks.Ip, byteToHexStr));
|
139
|
|
- handleResponse(sks, byteToHexStr);
|
140
|
|
- }
|
141
|
|
- else
|
142
|
|
- {
|
143
|
|
- isStartHeartbeat = false;
|
144
|
|
- addToListboxItem("状态信息:服务端主动关闭!");
|
145
|
|
- sockeTcpClients.Stop();
|
146
|
|
- }
|
147
|
|
- // listBoxShow.Text += "\r\n";
|
148
|
|
- // listBoxShow.Text += string.Format("服务端{0}发来消息:{1}", sks.Ip, byteToHexStr);
|
|
160
|
+ addToListboxItem("状态信息:服务端主动关闭! position");
|
|
161
|
+ sockeTcpClients.Stop();
|
149
|
162
|
}
|
|
163
|
+ // listBoxShow.Text += "\r\n";
|
|
164
|
+ // listBoxShow.Text += string.Format("服务端{0}发来消息:{1}", sks.Ip, byteToHexStr);
|
150
|
165
|
}
|
151
|
166
|
}));
|
152
|
167
|
}
|
153
|
168
|
|
154
|
|
- //处理回复信息
|
|
169
|
+ /// <summary>
|
|
170
|
+ /// 处理回复信息
|
|
171
|
+ /// </summary>
|
|
172
|
+ /// <param name="sks">Socket对象</param>
|
|
173
|
+ /// <param name="reqData">服务器发过来的信息</param>
|
155
|
174
|
private void handleResponse(SocketHelper.Sockets sks, string reqData)
|
156
|
175
|
{
|
157
|
176
|
//取出原数据功能码
|
158
|
177
|
string functionWord = reqData.Substring(18, 2);
|
159
|
178
|
int funcode = Utils.hexToTen(functionWord);
|
160
|
179
|
|
|
180
|
+
|
|
181
|
+ //处理心跳的回复
|
|
182
|
+ if (funcode == 4)
|
|
183
|
+ {
|
|
184
|
+ string hbLen = reqData.Substring(20, 4);
|
|
185
|
+
|
|
186
|
+ if (ToolStripMenuItemLogHb.Checked && hbLen.Equals("0000"))
|
|
187
|
+ {
|
|
188
|
+ addToListboxItem(string.Format("收到服务端{0}发来心跳:[{1}]", sks.Ip, reqData));
|
|
189
|
+ }
|
|
190
|
+ }
|
|
191
|
+ else
|
|
192
|
+ {
|
|
193
|
+ addToListboxItem(string.Format("收到服务端{0}发来消息:[{1}]", sks.Ip, reqData));
|
|
194
|
+ }
|
|
195
|
+
|
161
|
196
|
if (!(funcode == 16 || funcode == 32))
|
162
|
197
|
{
|
163
|
198
|
Console.WriteLine("功能码10进制=" + funcode + ",所以不用回复!");
|
|
@@ -256,6 +291,23 @@ namespace GWSocketClient
|
256
|
291
|
tsslEquipmentAddress.Text = equipmentAddress.Length / 2.0 + "";
|
257
|
292
|
}
|
258
|
293
|
|
|
294
|
+
|
|
295
|
+ private void sendLoginCmd()
|
|
296
|
+ {
|
|
297
|
+ // string loginCmd = "7e7e7e4442832e833c8200143839383630324231313931353530343739383737f7";
|
|
298
|
+ string loginCmd = vcarecityProtocolBean.ProtocolStartSymbol;
|
|
299
|
+ loginCmd += tbEquipmentAddress.Text.Trim() + "82" +
|
|
300
|
+ Utils.stringWith0(Utils.tenToHex(tbCCID.Text.Trim().Length / 2), 4);
|
|
301
|
+ loginCmd += tbCCID.Text.Trim();
|
|
302
|
+ loginCmd = Utils.calcCrcCode(loginCmd);
|
|
303
|
+ //发送登录命令
|
|
304
|
+ byte[] ts = HexUtil.hexToBytes(loginCmd);
|
|
305
|
+
|
|
306
|
+ addToListboxItem(string.Format("发送到服务端:[{0}]", loginCmd));
|
|
307
|
+
|
|
308
|
+ sockeTcpClients.SendData(ts);
|
|
309
|
+ }
|
|
310
|
+
|
259
|
311
|
private void btnLogin_Click(object sender, EventArgs e)
|
260
|
312
|
{
|
261
|
313
|
try
|
|
@@ -268,19 +320,6 @@ namespace GWSocketClient
|
268
|
320
|
|
269
|
321
|
sockeTcpClients.InitSocket(ip, int.Parse(port));
|
270
|
322
|
sockeTcpClients.Start();
|
271
|
|
-
|
272
|
|
- // string loginCmd = "7e7e7e4442832e833c8200143839383630324231313931353530343739383737f7";
|
273
|
|
- string loginCmd = vcarecityProtocolBean.ProtocolStartSymbol;
|
274
|
|
- loginCmd += tbEquipmentAddress.Text.Trim() + "82" +
|
275
|
|
- Utils.stringWith0(Utils.tenToHex(tbCCID.Text.Trim().Length / 2), 4);
|
276
|
|
- loginCmd += tbCCID.Text.Trim();
|
277
|
|
- loginCmd = Utils.calcCrcCode(loginCmd);
|
278
|
|
- //发送登录命令
|
279
|
|
- byte[] ts = HexUtil.hexToBytes(loginCmd);
|
280
|
|
-
|
281
|
|
- addToListboxItem(string.Format("发送到服务端:[{0}]", loginCmd));
|
282
|
|
-
|
283
|
|
- sockeTcpClients.SendData(ts);
|
284
|
323
|
}
|
285
|
324
|
catch (Exception ex)
|
286
|
325
|
{
|
|
@@ -299,7 +338,6 @@ namespace GWSocketClient
|
299
|
338
|
|
300
|
339
|
private void btnQuickLogout_Click(object sender, EventArgs e)
|
301
|
340
|
{
|
302
|
|
- isStartHeartbeat = false;
|
303
|
341
|
try
|
304
|
342
|
{
|
305
|
343
|
sockeTcpClients.Stop();
|
|
@@ -525,11 +563,21 @@ namespace GWSocketClient
|
525
|
563
|
ToolStripMenuItemLogHb.Checked = !ToolStripMenuItemLogHb.Checked;
|
526
|
564
|
}
|
527
|
565
|
|
528
|
|
- private void ToolStripMenuItemHbStart_Click(object sender, EventArgs e)
|
|
566
|
+
|
|
567
|
+ private void checkLogin(bool isLogin)
|
529
|
568
|
{
|
530
|
|
- ToolStripMenuItemHbStart.Checked = !ToolStripMenuItemHbStart.Checked;
|
|
569
|
+ if (isLogin)
|
|
570
|
+ {
|
|
571
|
+ btnLogin.Enabled = false;
|
|
572
|
+ btnQuickLogout.Enabled = true;
|
|
573
|
+ btnSendData.Enabled = true;
|
|
574
|
+ }
|
|
575
|
+ else
|
|
576
|
+ {
|
|
577
|
+ btnLogin.Enabled = true;
|
|
578
|
+ btnQuickLogout.Enabled = false;
|
|
579
|
+ btnSendData.Enabled = false;
|
|
580
|
+ }
|
531
|
581
|
}
|
532
|
|
-
|
533
|
|
-
|
534
|
582
|
}
|
535
|
583
|
}
|