Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

496 строки
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. //Console.WriteLine("{0} {1}",head.SeqNO, bytesSend.ToHexString());
  267. //发送消息
  268. SendBytes(tcp, bytesSend);
  269. //控制台打印日志cpu占用太高
  270. if (sendLogPrint)
  271. {
  272. Console.WriteLine("{0} {1}, LatLon:{2:0.000000},{3:0.000000}", head.GetDeviceId(), DateTime.Now.ToString(), lat, lon);
  273. }
  274. //等待接收服务端返回值
  275. var success = true;
  276. if (waitReceive)
  277. {
  278. success = RecvBytes(tcp);
  279. //var success = true;
  280. }
  281. return success;
  282. }
  283. void SendBytes(Socket tcp, byte[] bytes)
  284. {
  285. lock (System.Reflection.MethodBase.GetCurrentMethod())
  286. {
  287. if (bytes.Length != tcp.Send(bytes))
  288. {
  289. throw new SocketException((int)SocketError.ConnectionReset);
  290. }
  291. }
  292. }
  293. private bool RecvBytes(Socket tcp)
  294. {
  295. lock (bufferRecv)
  296. {
  297. byte[] buffer = bufferRecv;
  298. int received = tcp.Receive(buffer);
  299. //received = tcp.ReceiveAsync.Receive(buffer);
  300. byte[] bytesReceived = PackHelper.DecodeBytes(buffer, 1, received - 2);
  301. int rightSize = HeadPack.PackSize + ServerAnswerPack.PackSize + 1;
  302. if (bytesReceived.Length != rightSize)
  303. {
  304. log.WarnFormat("返回消息长度不正确:" + bytesReceived.Length + "!=" + rightSize);
  305. }
  306. ServerAnswerPack pack = new ServerAnswerPack();
  307. RawFormatter.Instance.Bytes2Struct(pack, bytesReceived, HeadPack.PackSize, ServerAnswerPack.PackSize);
  308. if (pack.Result != 0)
  309. {
  310. log.WarnFormat("发送失败:" + pack.Result.ToString());
  311. }
  312. if(waitReceive && receiveLogPrint)
  313. {
  314. Console.WriteLine("SeqNO:{0} MessageId:{1} Result:{2}", pack.SeqNO,pack.MessageId,pack.Result);
  315. }
  316. return pack.Result == 0;
  317. }
  318. }
  319. static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
  320. {
  321. log.Error(e.ExceptionObject);
  322. }
  323. }
  324. class LatlonBuilder
  325. {
  326. private double lat;
  327. private double lon;
  328. private double minLat;
  329. private double maxLat;
  330. private double minLon;
  331. private double maxLon;
  332. private int direction = 0;
  333. private Random r = new Random();
  334. public LatlonBuilder(double lat, double lon, double minLat, double maxlat, double minLon, double maxLon)
  335. {
  336. this.lat = lat;
  337. this.lon = lon;
  338. this.minLat = minLat;
  339. this.maxLat = maxlat;
  340. this.minLon = minLon;
  341. this.maxLon = maxLon;
  342. this.direction = r.Next(360);
  343. }
  344. public bool GetNextLatlon(int speed, out double lat, out double lon)
  345. {
  346. direction = (direction + (r.Next(30) - 15)) % 360;
  347. double angle = Math.PI * this.direction / 180.0;
  348. double latAdd = speed / 1000.0 * Math.Sin(angle);
  349. double lonAdd = speed / 1000.0 * Math.Cos(angle);
  350. this.lat = lat = this.lat + latAdd;
  351. this.lon = lon = this.lon + lonAdd;
  352. if (lat < minLat || lat > maxLat || lon < minLon || lon > maxLon)
  353. {
  354. direction = (direction + 180) % 360;
  355. return GetNextLatlon(speed, out lat, out lon);
  356. }
  357. return true;
  358. }
  359. }
  360. class ProcessCounter
  361. {
  362. private long current = 0, failedCounter = 0;
  363. private Thread thread;
  364. private AutoResetEvent evtUpdateUI = new AutoResetEvent(false);
  365. private long updatePerCount;
  366. private long lastUpdateVal;
  367. public ProcessCounter(long max, Action<ProcessCounter> updateUI)
  368. {
  369. this.Max = max;
  370. this.updatePerCount = max / 100;
  371. this.thread = new Thread(new ThreadStart(() =>
  372. {
  373. while (true)
  374. {
  375. try
  376. {
  377. evtUpdateUI.WaitOne(500);
  378. this.lastUpdateVal = Interlocked.Read(ref current);
  379. updateUI(this);
  380. }
  381. catch (ThreadAbortException)
  382. {
  383. return;
  384. }
  385. catch (Exception exp)
  386. {
  387. Console.WriteLine(exp.Message);
  388. }
  389. }
  390. }));
  391. this.thread.IsBackground = true;
  392. this.thread.Start();
  393. }
  394. public long Max { get; set; }
  395. internal void IncrSuccess()
  396. {
  397. lock (this)
  398. Incr();
  399. }
  400. internal void IncrFailed()
  401. {
  402. lock (this)
  403. {
  404. Incr();
  405. Interlocked.Increment(ref failedCounter);
  406. }
  407. }
  408. private void Incr()
  409. {
  410. var val = Interlocked.Increment(ref current);
  411. if (val - lastUpdateVal > this.updatePerCount)
  412. {
  413. this.evtUpdateUI.Set();
  414. }
  415. if (val == Max)
  416. {
  417. Console.WriteLine("Done");
  418. }
  419. }
  420. public override string ToString()
  421. {
  422. long curr = Interlocked.Read(ref current);
  423. float g = Convert.ToSingle(curr / (Max / 100.0));
  424. string ret = string.Concat(curr, "/", Max, "=>", g.ToString("##.00"), "%");
  425. long failed = Interlocked.Read(ref failedCounter);
  426. if (failed > 0)
  427. ret = string.Concat(ret, "(Success:" + (curr - failed), ", Failed:", failed, ")");
  428. return ret;
  429. }
  430. }
  431. }