選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

494 行
17 KiB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Net.Sockets;
  6. using System.Net;
  7. using System.Diagnostics;
  8. using System.Threading;
  9. using Gps.Plugin.Tcp.GT808;
  10. using Gps.Plugin.Common.Helpers;
  11. using System.Configuration;
  12. namespace GT808ClientTest
  13. {
  14. class Program
  15. {
  16. protected static log4net.ILog log = null;
  17. private string ip;
  18. private int port;
  19. private string deviceId;
  20. Random r = new Random();
  21. private int interval;
  22. private int sendCountByOneDevice;
  23. private ProcessCounter processCounter;
  24. private static bool sendLogPrint;
  25. private static bool waitReceive;
  26. private static bool receiveLogPrint;
  27. static Program()
  28. {
  29. log4net.Config.XmlConfigurator.ConfigureAndWatch(new System.IO.FileInfo(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile));
  30. log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
  31. }
  32. private double initLat = 38.01342;
  33. private double initLon = 114.560478;
  34. public Program(string ip, int port, string deviceId, int interval, int sendCountByOneDevice, ProcessCounter processCounter)
  35. {
  36. // TODO: Complete member initialization
  37. this.latlonBuilder = new LatlonBuilder(initLat, initLon, 31.802893, 39.300299, 104.941406, 117.861328);
  38. this.ip = ip;
  39. this.port = port;
  40. this.deviceId = deviceId;
  41. this.interval = interval;
  42. this.sendCountByOneDevice = sendCountByOneDevice;
  43. this.processCounter = processCounter;
  44. }
  45. private static byte[] stringtobytes(string str)
  46. {
  47. string[] strs = str.Split(new char[] { '-' }, StringSplitOptions.RemoveEmptyEntries);
  48. byte[] buffer = new byte[strs.Length];
  49. for (int i = 0; i < strs.Length; ++i)
  50. {
  51. buffer[i] = Convert.ToByte(strs[i], 16);
  52. }
  53. return buffer;
  54. }
  55. static void Main(string[] args)
  56. {
  57. AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
  58. //var headpack = new Gps.Plugin.Tcp.GT808.HeadPack();
  59. //byte[] packBytes = stringtobytes("7E-01-02-00-0E-00-20-47-05-52-32-00-00-32-30-31-32-30-31-31-39-30-38-31-30-34-37-0D-7E");
  60. //if (RawFormatter.Instance.Bytes2Struct(headpack, packBytes , 1, HeadPack.PackSize))
  61. //{
  62. // Console.WriteLine("OK");
  63. // Console.ReadKey();
  64. //}
  65. //MessageContext pack = new MessageContext();
  66. //byte[] packBytes = stringtobytes("68-68-25-00-00-00-00-00-00-00-12-34-56-00-18-10-DC-01-13-13-06-17-04-14-11-DC-0C-4A-7F-5C-1A-00-00-00-00-00-00-00-00-00-0A-0D");
  67. //if (RawFormatter.Instance.Bytes2Struct(pack, packBytes, BodyData.PackSize, MessageContext.PackSize))
  68. //{
  69. // Console.WriteLine("OK");
  70. // Console.ReadKey();
  71. //}
  72. sendLogPrint = Convert.ToBoolean(ConfigurationManager.AppSettings["sendLogPrint"]);
  73. waitReceive = Convert.ToBoolean(ConfigurationManager.AppSettings["waitReceive"]);
  74. receiveLogPrint = Convert.ToBoolean(ConfigurationManager.AppSettings["receiveLogPrint"]);
  75. string ip = "";
  76. int port = 0;
  77. while (port == 0 || string.IsNullOrEmpty(ip))
  78. {
  79. string line = "";
  80. string configValue = ConfigurationManager.AppSettings["remoteServerPort"];
  81. if (string.IsNullOrEmpty(configValue))
  82. {
  83. Console.Write("请输入服务器IP和端口(113.31.92.200:8201):");
  84. line = Console.ReadLine();
  85. }
  86. else
  87. {
  88. line = configValue;
  89. }
  90. if (string.IsNullOrEmpty(line))
  91. line = "113.31.92.200:8201";
  92. int pos = line.IndexOf(':');
  93. if (pos == -1)
  94. {
  95. Console.WriteLine("正确格式:xx.xxx.xxx.xxx:xxxx");
  96. continue;
  97. }
  98. ip = line.Substring(0, pos);
  99. string strPort = line.Substring(pos + 1);
  100. int.TryParse(strPort, out port);
  101. }
  102. int min = 0, max = 0;
  103. string deviceIdRangeValue = ConfigurationManager.AppSettings["deviceIdRange"];
  104. if (string.IsNullOrEmpty(deviceIdRangeValue))
  105. {
  106. Console.WriteLine("生成设备标识格式为:0000000000000000,0000000000000001....");
  107. Console.Write("依客户端网络情况输入要模拟的客户端数量(1-10000):");
  108. string strCount = Console.ReadLine();
  109. max = int.Parse(strCount);
  110. }
  111. else
  112. {
  113. string[] items = deviceIdRangeValue.Split('-');
  114. min = int.Parse(items[0]);
  115. max = int.Parse(items[1]);
  116. }
  117. int interval = 30;
  118. string strInterval = ConfigurationManager.AppSettings["interval"];
  119. if (string.IsNullOrEmpty(strInterval))
  120. {
  121. Console.Write("每个消息间隔(秒):");
  122. strInterval = Console.ReadLine();
  123. interval = int.Parse(strInterval);
  124. }
  125. else
  126. {
  127. interval = int.Parse(strInterval);
  128. }
  129. int sendCountByOneDevice = 30;
  130. string strSendCountByOneDevice = ConfigurationManager.AppSettings["sendCountByOneDevice"];
  131. if (string.IsNullOrEmpty(strSendCountByOneDevice))
  132. {
  133. Console.Write("每个设备发送共多少个包后断开连接:");
  134. strSendCountByOneDevice = Console.ReadLine();
  135. sendCountByOneDevice = int.Parse(strSendCountByOneDevice);
  136. }
  137. else
  138. {
  139. sendCountByOneDevice = int.Parse(strSendCountByOneDevice);
  140. }
  141. ProcessCounter processCounter = new ProcessCounter((max - min + 1) * sendCountByOneDevice, pc =>
  142. {
  143. Console.Title = pc.ToString();
  144. });
  145. for (int i = min; i <= max; ++i)
  146. {
  147. string deviceId = string.Concat("010000", i.ToString("00000"));
  148. Program p = new Program(ip, port, deviceId, interval, sendCountByOneDevice, processCounter);
  149. //p.Run();
  150. Thread iThred = new Thread(p.Run);
  151. iThred.Start();
  152. //Thread.SpinWait(2);
  153. }
  154. Console.ReadLine();
  155. }
  156. private void Run()
  157. {
  158. Console.WriteLine("Thread {0} Start {1}", Thread.CurrentThread.ManagedThreadId, DateTime.Now.ToString());
  159. Socket tcp = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  160. try
  161. {
  162. tcp.Connect(IPAddress.Parse(ip), port);
  163. try
  164. {
  165. while (this.sendCountByOneDevice-- > 0)
  166. {
  167. if (SendPosition(tcp))
  168. {
  169. processCounter.IncrSuccess();
  170. }
  171. else
  172. {
  173. processCounter.IncrFailed();
  174. }
  175. Thread.Sleep(interval * 1000);
  176. //Thread.Sleep(100);
  177. }
  178. /*
  179. if (SendPosition(tcp))
  180. {
  181. processCounter.IncrSuccess();
  182. }
  183. else
  184. {
  185. processCounter.IncrFailed();
  186. }
  187. if (--this.sendCountByOneDevice <= 0)
  188. {
  189. //timer.Change(-1, -1);
  190. //try
  191. //{
  192. // tcp.Disconnect(true);
  193. // tcp.Dispose();
  194. //}
  195. //catch (Exception exp)
  196. //{
  197. // log.Warn("断开连接出错:" + exp.Message);
  198. //}
  199. }
  200. else
  201. {
  202. //SendPosition(tcp);
  203. //timer.Change(Math.Max(1, interval * 1000 - watch.ElapsedMilliseconds), -1);
  204. }
  205. */
  206. }
  207. catch (SocketException exp)
  208. {
  209. log.Debug("连接已经断开, 重连接中");
  210. //timer.Change(Timeout.Infinite, Timeout.Infinite);
  211. this.Run();
  212. }
  213. catch (Exception ex)
  214. {
  215. log.Error(ex.Message, ex);
  216. //timer.Change(Math.Max(1, interval * 1000 - watch.ElapsedMilliseconds), -1);
  217. }
  218. }
  219. catch (ThreadAbortException)
  220. {
  221. return;
  222. }
  223. catch (Exception exp)
  224. {
  225. log.Error(exp);
  226. }
  227. Console.WriteLine("Thread {0} End {1}", Thread.CurrentThread.ManagedThreadId, DateTime.Now.ToString());
  228. }
  229. ushort seqNum = 1;
  230. ushort GetNextSeqNum()
  231. {
  232. lock (this)
  233. {
  234. return ++seqNum;
  235. }
  236. }
  237. private byte[] bufferRecv = new byte[1024];
  238. private LatlonBuilder latlonBuilder;
  239. private bool SendPosition(Socket tcp)
  240. {
  241. HeadPack head = new HeadPack() { SeqNO = GetNextSeqNum(), MessageId = (ushort)MessageIds.PositionReport, BodyProp = (ushort)0 };
  242. head.SetDeviceId(this.deviceId);
  243. double lat;
  244. double lon;
  245. int speed = 10 + r.Next(90);
  246. latlonBuilder.GetNextLatlon(speed, out lat, out lon);
  247. PositionReportPack pack = new PositionReportPack()
  248. {
  249. AlermFlags = 0,
  250. Speed = (ushort)(speed * 10),
  251. State = 0,
  252. Latitude = Convert.ToUInt32(lat * 1000000),
  253. Longitude = Convert.ToUInt32(lon * 1000000),
  254. Altitude = 200,
  255. Direction = 0,
  256. Time = DateTime.Now.ToString("yyMMddHHmmss")
  257. };
  258. byte[] bytesSend = RawFormatter.Instance.Struct2Bytes(pack);
  259. BodyPropertyHelper.SetMessageLength(ref head.BodyProp, (ushort)bytesSend.Length);
  260. byte[] headBytes = RawFormatter.Instance.Struct2Bytes(head);
  261. byte[] fullBytes = headBytes.Concat(bytesSend).ToArray();
  262. byte checkByte = PackHelper.CalcCheckByte(fullBytes, 0, fullBytes.Length);
  263. bytesSend = (new byte[] { 0x7e }
  264. .Concat(PackHelper.EncodeBytes(fullBytes).Concat(new byte[] { checkByte }))
  265. .Concat(new byte[] { 0x7e })).ToArray();
  266. //发送消息
  267. SendBytes(tcp, bytesSend);
  268. //控制台打印日志cpu占用太高
  269. if (sendLogPrint)
  270. {
  271. Console.WriteLine("{0} {1}, LatLon:{2:0.000000},{3:0.000000}", head.GetDeviceId(), DateTime.Now.ToString(), lat, lon);
  272. }
  273. //等待接收服务端返回值
  274. var success = true;
  275. if (waitReceive)
  276. {
  277. success = RecvBytes(tcp);
  278. //var success = true;
  279. }
  280. return success;
  281. }
  282. void SendBytes(Socket tcp, byte[] bytes)
  283. {
  284. lock (System.Reflection.MethodBase.GetCurrentMethod())
  285. {
  286. if (bytes.Length != tcp.Send(bytes))
  287. {
  288. throw new SocketException((int)SocketError.ConnectionReset);
  289. }
  290. }
  291. }
  292. private bool RecvBytes(Socket tcp)
  293. {
  294. lock (bufferRecv)
  295. {
  296. byte[] buffer = bufferRecv;
  297. int received = tcp.Receive(buffer);
  298. //received = tcp.ReceiveAsync.Receive(buffer);
  299. byte[] bytesReceived = PackHelper.DecodeBytes(buffer, 1, received - 2);
  300. int rightSize = HeadPack.PackSize + ServerAnswerPack.PackSize + 1;
  301. if (bytesReceived.Length != rightSize)
  302. {
  303. log.WarnFormat("返回消息长度不正确:" + bytesReceived.Length + "!=" + rightSize);
  304. }
  305. ServerAnswerPack pack = new ServerAnswerPack();
  306. RawFormatter.Instance.Bytes2Struct(pack, bytesReceived, HeadPack.PackSize, ServerAnswerPack.PackSize);
  307. if (pack.Result != 0)
  308. {
  309. log.WarnFormat("发送失败:" + pack.Result.ToString());
  310. }
  311. if(waitReceive && receiveLogPrint)
  312. {
  313. Console.WriteLine("SeqNO:{0} MessageId:{1} Result:{2}", pack.SeqNO,pack.MessageId,pack.Result);
  314. }
  315. return pack.Result == 0;
  316. }
  317. }
  318. static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
  319. {
  320. log.Error(e.ExceptionObject);
  321. }
  322. }
  323. class LatlonBuilder
  324. {
  325. private double lat;
  326. private double lon;
  327. private double minLat;
  328. private double maxLat;
  329. private double minLon;
  330. private double maxLon;
  331. private int direction = 0;
  332. private Random r = new Random();
  333. public LatlonBuilder(double lat, double lon, double minLat, double maxlat, double minLon, double maxLon)
  334. {
  335. this.lat = lat;
  336. this.lon = lon;
  337. this.minLat = minLat;
  338. this.maxLat = maxlat;
  339. this.minLon = minLon;
  340. this.maxLon = maxLon;
  341. this.direction = r.Next(360);
  342. }
  343. public bool GetNextLatlon(int speed, out double lat, out double lon)
  344. {
  345. direction = (direction + (r.Next(30) - 15)) % 360;
  346. double angle = Math.PI * this.direction / 180.0;
  347. double latAdd = speed / 1000.0 * Math.Sin(angle);
  348. double lonAdd = speed / 1000.0 * Math.Cos(angle);
  349. this.lat = lat = this.lat + latAdd;
  350. this.lon = lon = this.lon + lonAdd;
  351. if (lat < minLat || lat > maxLat || lon < minLon || lon > maxLon)
  352. {
  353. direction = (direction + 180) % 360;
  354. return GetNextLatlon(speed, out lat, out lon);
  355. }
  356. return true;
  357. }
  358. }
  359. class ProcessCounter
  360. {
  361. private long current = 0, failedCounter = 0;
  362. private Thread thread;
  363. private AutoResetEvent evtUpdateUI = new AutoResetEvent(false);
  364. private long updatePerCount;
  365. private long lastUpdateVal;
  366. public ProcessCounter(long max, Action<ProcessCounter> updateUI)
  367. {
  368. this.Max = max;
  369. this.updatePerCount = max / 100;
  370. this.thread = new Thread(new ThreadStart(() =>
  371. {
  372. while (true)
  373. {
  374. try
  375. {
  376. evtUpdateUI.WaitOne(500);
  377. this.lastUpdateVal = Interlocked.Read(ref current);
  378. updateUI(this);
  379. }
  380. catch (ThreadAbortException)
  381. {
  382. return;
  383. }
  384. catch (Exception exp)
  385. {
  386. Console.WriteLine(exp.Message);
  387. }
  388. }
  389. }));
  390. this.thread.IsBackground = true;
  391. this.thread.Start();
  392. }
  393. public long Max { get; set; }
  394. internal void IncrSuccess()
  395. {
  396. lock (this)
  397. Incr();
  398. }
  399. internal void IncrFailed()
  400. {
  401. lock (this)
  402. {
  403. Incr();
  404. Interlocked.Increment(ref failedCounter);
  405. }
  406. }
  407. private void Incr()
  408. {
  409. var val = Interlocked.Increment(ref current);
  410. if (val - lastUpdateVal > this.updatePerCount)
  411. {
  412. this.evtUpdateUI.Set();
  413. }
  414. if (val == Max)
  415. {
  416. Console.WriteLine("Done");
  417. }
  418. }
  419. public override string ToString()
  420. {
  421. long curr = Interlocked.Read(ref current);
  422. float g = Convert.ToSingle(curr / (Max / 100.0));
  423. string ret = string.Concat(curr, "/", Max, "=>", g.ToString("##.00"), "%");
  424. long failed = Interlocked.Read(ref failedCounter);
  425. if (failed > 0)
  426. ret = string.Concat(ret, "(Success:" + (curr - failed), ", Failed:", failed, ")");
  427. return ret;
  428. }
  429. }
  430. }