private byte[] ConstructAckData(GPRSMsg msg) { byte[] heartTick = new byte[40 + msg.MsgLen]; int index = 0; for (int i = 0; i < msg.DtuID.Length; i++) { heartTick[index] = msg.DtuID[i]; index++; } for (int i = 0; i < msg.DtuIMEI.Length; i++) { heartTick[index] = msg.DtuIMEI[i]; index++; } for (int i = 0; i < msg.DtuName.Length; i++) { heartTick[index] = msg.DtuName[i]; index++; } heartTick[index++] = msg.MsgType; heartTick[index++] = 0; heartTick[index++] = (byte)(msg.MsgLen >> 8); heartTick[index++] = (byte)msg.MsgLen; Array.Copy(msg.MsgBody, 0, heartTick, index, msg.MsgLen); return(heartTick); }
public byte[] ConstructAckMsg(GPRSMsg msg, byte reserved, byte msgType) { string strAck = string.Format("+TOPSAIL{0}{1}", DateTime.Now.Year - 2000, DateTime.Now.ToString("MMddHHmmss")); byte[] bytesAck = Encoding.ASCII.GetBytes(strAck); return(bytesAck); }
// processing connection from DTU private void RunTcpClient(object obj) { TcpClient client = obj as TcpClient; //client.Client.Blocking = true; client.NoDelay = true; int timeout = 60 * 1000 * 6; // 设置为心跳超时 int waitUnit = 100; // 100 ms int ntotalWait = 0; const int regWaitTime = 60 * 1000 * 3; int regNowWaitTime = 0; DTUInfo dtuInfo = new DTUInfo(); //NetworkStream ns = client.GetStream(); GPRSMsg msg = new GPRSMsg(); System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch(); while (true) { if (stopTag) { break; } if (!client.Connected) { return; } try { if (client.Client.Poll(0, SelectMode.SelectRead) && (!client.Client.Poll(0, SelectMode.SelectError))) // client close connection positive { if (client.Available == 0) { break; } } } catch (Exception ex) { break; } NetworkStream ns = client.GetStream(); if (!ns.DataAvailable) { Thread.Sleep(waitUnit); // sleep 100ms ntotalWait += waitUnit; if (!dtuInfo.IsRegisted) { regNowWaitTime += waitUnit; if (regNowWaitTime > regWaitTime) { break; } else { continue; } } else { if (ntotalWait > timeout) { break; } } continue; } stopWatch.Reset(); stopWatch.Start(); if (client.Available == 0) // client close connection positive { break; } //ntotalWait = 0; try { byte[] header = new byte[4]; byte[] msgLen = new byte[2]; ns.Read(header, 0, 4); if (header[0] == msg.DtuID[0] && header[1] == msg.DtuID[1] && header[2] == msg.DtuID[2] && header[3] == msg.DtuID[3]) { ns.Read(msg.DtuIMEI, 0, 16); ns.Read(msg.DtuName, 0, 16); msg.MsgType = (byte)ns.ReadByte(); msg.Reserved = (byte)ns.ReadByte(); ns.Read(msgLen, 0, 2); msg.MsgLen = (ushort)((msgLen[0] << 8) + msgLen[1]); msg.MsgBody = new byte[msg.MsgLen]; ns.Read(msg.MsgBody, 0, msg.MsgLen); #region Register Of DTU if (msg.MsgType == (byte)MsgID.DTURegister) { dtuInfo.IsRegisted = true; timeout = ((msg.MsgBody[0] << 8) + msg.MsgBody[1]) * 1000; // unit ms if (timeout < 120 * 1000) { timeout = 120 * 1000; } dtuInfo.Online = true; dtuInfo.LoginTime = DateTime.Now; dtuInfo.TickSpan = (int)(timeout / 1000); dtuInfo.RemoteIPAddress = ((IPEndPoint)client.Client.RemoteEndPoint).Address.ToString(); dtuInfo.IMEIString = ASCIIEncoding.ASCII.GetString(msg.DtuIMEI, 0, 15); // query database by imei get dtu info dtuInfo.SimNumber = "13500000000"; dtuInfo.DtuPosition = "未知"; if (RegisteChangedHandle != null) { RegisteChangedHandle(this, new RegisterInfoArgs(dtuInfo)); } if (DtuOnlineChangeHandle != null) { DtuOnlineChangeHandle(this, new RegisterInfoArgs(dtuInfo)); } lock (this) { if (!dicDtuConn.ContainsKey(dtuInfo.IMEIString)) { dicDtuConn.Add(dtuInfo.IMEIString, client); } else { dicDtuConn[dtuInfo.IMEIString] = client; } } byte[] tempAck = ConstructAckMsg(); ns.Write(tempAck, 0, tempAck.Length); } #endregion #region DTU Data if (msg.MsgType == (byte)MsgID.DTUData) { if (!dtuInfo.IsRegisted) { break; } else { try { byte[] tempAck = ConstructAckMsg(); ns.Write(tempAck, 0, tempAck.Length); } catch (Exception ex) { } if (DataReceivedHandle != null) { DataReceivedHandle(this, new DataComeArgs(msg)); lock (this) { // 解析数据,存入数据库 } } } } #endregion #region DTU Cmd if (msg.MsgType == (byte)MsgID.DTUATCmd) { if (!dtuInfo.IsRegisted) { break; } else { } } #endregion #region DTU HeartTick if (msg.MsgType == (byte)MsgID.DTUHeartTick) { if (!dtuInfo.IsRegisted) { break; } } #endregion #region DTUP2P if (msg.MsgType == (byte)MsgID.DTUP2P) { if (!dtuInfo.IsRegisted) { break; } else { List <string> listDtu = new List <string>(); byte reserved = 0; if (msg.MsgLen % 16 != 0) { reserved = 0xff; } else { byte[] tempBuf = new byte[16]; for (int i = 0; i < msg.MsgLen; i += 16) { Array.Copy(msg.MsgBody, i, tempBuf, 0, 16); listDtu.Add(ASCIIEncoding.ASCII.GetString(tempBuf, 0, 15)); } lock (this) { if (!dicDtuP2PConfig.ContainsKey(dtuInfo.IMEIString)) { dicDtuP2PConfig.Add(dtuInfo.IMEIString, listDtu); } else { dicDtuP2PConfig[dtuInfo.IMEIString] = listDtu; } } dtuInfo.ListP2PDTU.Clear(); dtuInfo.ListP2PDTU.AddRange(listDtu); // 此处用于更新P2P通信是对端IMEI列表 if (RegisteChangedHandle != null) { RegisteChangedHandle(this, new RegisterInfoArgs(dtuInfo)); } } byte[] tempAck = ConstructAckMsg(msg, reserved, (byte)MsgID.DTUP2P); ns.Write(tempAck, 0, tempAck.Length); } } #endregion } else { break; } } catch (Exception ex) { break; } stopWatch.Stop(); TimeSpan spanRun = stopWatch.Elapsed; ntotalWait += (int)spanRun.TotalSeconds; } stopWatch.Reset(); dtuInfo.Online = false; dtuInfo.LogoffTime = DateTime.Now; if (RegisteChangedHandle != null) { RegisteChangedHandle(this, new RegisterInfoArgs(dtuInfo)); } if (DtuOnlineChangeHandle != null) { DtuOnlineChangeHandle(this, new RegisterInfoArgs(dtuInfo)); } client.Client.Close(); client.Close(); lock (this) { if (dicDtuConn.ContainsKey(dtuInfo.IMEIString)) { dicDtuConn.Remove(dtuInfo.IMEIString); } } }
// processing connection from data center client private void RunTcpClientDCC(object obj) { TcpClient client = obj as TcpClient; client.NoDelay = true; int waitUnit = 100; int timeout = 60 * 9 * 1000; // 设置为心跳超时 9min //int nTotalCount = 0; string hostIP = ((IPEndPoint)client.Client.RemoteEndPoint).Address.ToString(); DCCConnInfo dccInfo = new DCCConnInfo(client); dccInfo.nNonAliveTick = 0; while (true) { if (stopTag) { break; } try { if (client.Client.Poll(0, SelectMode.SelectRead) && (!client.Client.Poll(0, SelectMode.SelectError))) // client close connection positive { if (client.Available == 0) { break; } } } catch (Exception ex) { break; } NetworkStream ns = client.GetStream(); if (!ns.DataAvailable) { Thread.Sleep(waitUnit); // sleep 100ms dccInfo.nNonAliveTick += waitUnit; if (dccInfo.nNonAliveTick > timeout) // when timeout eclipse, close client connection { break; } else { continue; } } dccInfo.nNonAliveTick = 0; GPRSMsg msg = new GPRSMsg(); try { byte[] header = new byte[4]; byte[] msgLen = new byte[2]; ns.Read(header, 0, 4); if (header[0] == msg.DtuID[0] && header[1] == msg.DtuID[1] && header[2] == msg.DtuID[2] && header[3] == msg.DtuID[3]) { msg.MsgType = (byte)ns.ReadByte(); ns.Read(msgLen, 0, 2); msg.MsgLen = (ushort)((msgLen[0] << 8) + msgLen[1]); msg.MsgBody = new byte[msg.MsgLen]; if (msg.MsgType == (byte)DCCMsgID.DCCRegister) { // uppdate DCC Window, by dcc online status if (DccOnlineChangeHandle != null) { DccOnlineChangeHandle(this, new DCCInfoArgs(hostIP, true)); } int nDevIDCount = (int)msg.MsgLen / 16; for (int i = 0; i < nDevIDCount; i++) { ns.Read(msg.DtuIMEI, 0, 16); dccInfo.deviceID.Add(System.Text.Encoding.Default.GetString(msg.DtuIMEI, 0, 15)); } lock (this) { userClientList.Add(dccInfo); } // send device online state UInt16 dccOnlineCount = 0; List <byte> listBuf = new List <byte>(); listBuf.Add(0x7e); listBuf.Add(0x7e); listBuf.Add(0x7e); listBuf.Add(0x7e); listBuf.Add((byte)(DCCMsgID.DCC_DTUStatus)); // msg id foreach (string devID in dccInfo.deviceID) { if (dicDtuConn.ContainsKey(devID)) { dccOnlineCount++; listBuf.AddRange(ASCIIEncoding.Default.GetBytes(devID)); listBuf.Add((byte)('\0')); listBuf.Add(0x1); // 0 -- offline;1 -- online } } listBuf.Insert(5, (byte)((dccOnlineCount * 17) >> 8)); listBuf.Insert(6, (byte)(dccOnlineCount * 17)); ns.Write(listBuf.ToArray(), 0, listBuf.Count); } } else { break; } } catch (Exception ex) { break; } } if (DccOnlineChangeHandle != null) { DccOnlineChangeHandle(this, new DCCInfoArgs(hostIP, false)); } client.Client.Close(); client.Close(); lock (this) { if (userClientList.Contains(dccInfo)) { userClientList.Remove(dccInfo); } } }
public DataComeArgs(GPRSMsg msg) { gprsMsg = msg; }
// processing connection from DTU private void RunGPSClient(object obj) { StringBuilder recvBuffer = new StringBuilder(); TcpClient client = obj as TcpClient; byte[] recvs = new byte[client.ReceiveBufferSize]; client.NoDelay = true; int waitUnit = 100; // 100 ms int ntotalWait = 0; DTUInfo dtuInfo = new DTUInfo(); GPRSMsg msg = new GPRSMsg(); System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch(); while (true) { if (stopTag) { break; } if (!client.Connected) { return; } try { if (client.Client.Poll(0, SelectMode.SelectRead) && (!client.Client.Poll(0, SelectMode.SelectError))) // client close connection positive { if (client.Available == 0) { break; } } } catch (Exception ex) { break; } NetworkStream ns = client.GetStream(); if (!ns.DataAvailable) { Thread.Sleep(waitUnit); // sleep 100ms continue; } stopWatch.Reset(); stopWatch.Start(); if (client.Available == 0) // client close connection positive { break; } try { int count = ns.Read(recvs, 0, client.ReceiveBufferSize); if (count > 0) { string strMsg = Encoding.Default.GetString(recvs, 0, count); recvBuffer.Append(strMsg); while (recvBuffer.Length > "+RESP".Length && recvBuffer.ToString().IndexOf("+RESP") == -1) { recvBuffer.Remove(0, 1); } //find the start pos,end process it string[] dataLines = recvBuffer.ToString().Split(new char[] { '$' }, StringSplitOptions.None); foreach (var ele in dataLines) { string[] dataSegs = ele.Split(new char[] { ',' }, StringSplitOptions.None); GPSInfo gps = new GPSInfo(); // GL300W,GV300W if (dataSegs.Length > 12) { gps.imei = dataSegs[2]; gps.longitude = dataSegs[11]; gps.latitude = dataSegs[12]; DateTime dt = DateTime.Now; if (DateTime.TryParseExact(dataSegs[13], "yyyyMMddHHmmss", null, DateTimeStyles.None, out dt)) { dt = dt.AddHours(8); gps.recvTime = dt.ToString("yyyy-MM-dd HH:mm:ss"); } else { gps.recvTime = dt.ToString("yyyy-MM-dd HH:mm:ss"); } if (GPSComeHandler != null) { GPSComeHandler(this, gps); } } } int lastIndex = recvBuffer.ToString().LastIndexOf('$'); if (lastIndex != -1) { recvBuffer.Remove(0, lastIndex + 1); } } } catch (Exception ex) { break; } stopWatch.Stop(); TimeSpan spanRun = stopWatch.Elapsed; ntotalWait += (int)spanRun.TotalSeconds; } stopWatch.Reset(); if (RegisteChangedHandle != null) { RegisteChangedHandle(this, new RegisterInfoArgs(dtuInfo)); } if (DtuOnlineChangeHandle != null) { DtuOnlineChangeHandle(this, new RegisterInfoArgs(dtuInfo)); } client.Client.Close(); client.Close(); }