/// <summary> /// 子线程主体 /// </summary> /// <param name="objData"></param> private static void ThreadHandler(object objData) { NetStructure.NormalDataStruct dataInfo = (NetStructure.NormalDataStruct)objData; while (true) { try { ReceiveByProtocol(dataInfo.stream, ref dataInfo); HandlerByProtocol(ref dataInfo); } catch (System.IO.IOException ioEx) { if (!ioEx.Message.Contains("远程主机强迫关闭了一个现有的连接") && !ioEx.Message.Contains("没有正确答复或连接的主机没有反应")) {//忽略设备断开连接的错误,因为可能是设备断电导致,下次上电会自动重连 db.InsertErrorInfo(enumSystemErrorCode.TcpMachineStreamException, ioEx, dataInfo.IpAddress, dataInfo.Content); } dataInfo.stream.Close(); dataInfo.stream.Dispose(); dataInfo.stream = null; if (netConnection.Keys.Contains(dataInfo.MachineId)) { netConnection.Remove(dataInfo.MachineId); } break; } catch (Exception ex) { db.InsertErrorInfo(enumSystemErrorCode.TcpMachineStreamException, ex, dataInfo.IpAddress, dataInfo.Content); } } }
public static string StartServer() { string strError = null; try { //清空原来所有实时数据 ClearRedisServer(); //数据下派 子线程 Thread threadSend = new Thread(DownScheduleHandler); threadSend.Start(); //异常日志写入子线程 Thread threadErrorInsert = new Thread(db.InsertErrorInfo); threadErrorInsert.Start(); //端口监听并接受数据 serverListen = new TcpListener(IPAddress.Any, SERVER_PORT_NUMBER); serverListen.Start(); keepListening = true; while (keepListening) { TcpClient serverReceive = serverListen.AcceptTcpClient(); NetStructure.NormalDataStruct dataInfo = new NetStructure.NormalDataStruct(); dataInfo.stream = serverReceive.GetStream(); dataInfo.IpAddress = ((IPEndPoint)serverReceive.Client.RemoteEndPoint).Address.ToString(); //子线程接收和处理信息 Thread ThreadHanler = new Thread(new ParameterizedThreadStart(ThreadHandler)); ThreadHanler.Start(dataInfo); } //ClientHanlderProductInfo info = new ClientHanlderProductInfo(); //info.HandlerTest(); } catch (SocketException socketEx) { db.InsertErrorInfo(enumSystemErrorCode.TcpListenerException, socketEx, "监听异常", null); strError = socketEx.Message; System.Net.NetworkInformation.IPGlobalProperties ipProperties = System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties(); IPEndPoint[] ipEndPoints = ipProperties.GetActiveTcpListeners(); foreach (IPEndPoint endPoint in ipEndPoints) { if (endPoint.Port == SERVER_PORT_NUMBER) { keepListening = true; strError = "操作成功"; break; } } } catch (Exception ex) { strError = ex.Message; db.InsertErrorInfo(enumSystemErrorCode.TcpListenerException, ex, "监听异常", null); } return(strError); }
/// <summary> /// 服务器返回结果编码 /// </summary> /// <param name="cmd"></param> /// <param name="byteResp"></param> /// <param name="buff"></param> public static void EncodeServerResp(enumCommandType cmd, byte[] byteResp, out byte[] buff) { NetStructure.NormalDataStruct data = new NetStructure.NormalDataStruct() { Code = cmd, FactoryNumber = FACTORY_NORMAL, contentLen = byteResp.Length, Content = byteResp }; EncodeData(data, out buff); }
/// <summary> /// 下派施工单编码 /// </summary> /// <param name="buff"></param> public static void EncodeSchedule(Schedules schedule, out byte[] buff) { byte[] content = new byte[1024]; int locIdx = 0, tempLen = 2; //机器码 byte[] machineBytes = ConvertHelper.Int16ToBytes(schedule.MachineId, true); Array.Copy(machineBytes, content, tempLen); locIdx += tempLen; //施工单编号 byte[] numberBytes = Encoding.ASCII.GetBytes(schedule.Number); tempLen = numberBytes.Length; content[locIdx++] = (byte)tempLen; Array.Copy(numberBytes, 0, content, locIdx, tempLen); locIdx += tempLen; //施工单商品总数量 byte[] countByte = ConvertHelper.Int32ToBytes(schedule.ProductCount, true); Array.Copy(countByte, 0, content, locIdx, 4); locIdx += 4; //上跳持续数量 countByte = ConvertHelper.Int16ToBytes(schedule.UpContinueCount, true); Array.Copy(countByte, 0, content, locIdx, 2); locIdx += 2; //落下持续数量 countByte = ConvertHelper.Int16ToBytes(schedule.DownContinueCount, true); Array.Copy(countByte, 0, content, locIdx, 2); locIdx += 2; //详细信息 byte[] detailBytes = Encoding.GetEncoding("GBK").GetBytes(schedule.DetailInfo); tempLen = detailBytes.Length; byte[] lengthByte = ConvertHelper.Int16ToBytes(tempLen, true); Array.Copy(lengthByte, 0, content, locIdx, 2); locIdx += 2; Array.Copy(detailBytes, 0, content, locIdx, tempLen); locIdx += tempLen; //注意事项 byte[] noticeBytes = Encoding.GetEncoding("GBK").GetBytes(schedule.NoticeInfo); tempLen = noticeBytes.Length; lengthByte = ConvertHelper.Int16ToBytes(tempLen, true); Array.Copy(lengthByte, 0, content, locIdx, 2); locIdx += 2; Array.Copy(noticeBytes, 0, content, locIdx, tempLen); locIdx += tempLen; NetStructure.NormalDataStruct data = new NetStructure.NormalDataStruct() { Code = enumCommandType.DOWN_SHEDULE_SEND, contentLen = locIdx, Content = content }; EncodeData(data, out buff); }
private static bool ReceiveByProtocol(NetworkStream ns, ref NetStructure.NormalDataStruct dataInfo) { bool result = false; byte[] byteHead = new byte[Coder.PROTOCOL_HEAD_COUNT]; if (!ReadBuffer(ns, Coder.PROTOCOL_HEAD_COUNT, byteHead)) { db.InsertErrorInfo(enumSystemErrorCode.TcpRecieveErr, null, "数据头读取超时", byteHead); return(result); } //int headIdx = 0; //while (true) //{ // if (byteHead[headIdx] == Coder.PROTOCOL_HEAD_START[0] && byteHead[headIdx + 1] == Coder.PROTOCOL_HEAD_START[1] && // byteHead[headIdx + 2] == Coder.PROTOCOL_HEAD_START[2] && byteHead[headIdx + 3] == Coder.PROTOCOL_HEAD_START[3]) // { // break; // } // headIdx++; // if (headIdx > Coder.PROTOCOL_HEAD_COUNT - 4) // { // ReadBuffer(ns, Coder.PROTOCOL_HEAD_COUNT, byteHead); // headIdx = 0; // } //} //if (headIdx > 0) //{ // byte[] byteTemp = new byte[headIdx]; // ReadBuffer(ns, headIdx, byteTemp); // for (int i = 0; i < Coder.PROTOCOL_HEAD_COUNT - headIdx; i++) // { // byteHead[i] = byteHead[i + headIdx]; // } // for (int i = Coder.PROTOCOL_HEAD_COUNT - headIdx; i < Coder.PROTOCOL_HEAD_COUNT; i++) // { // byteHead[i] = byteTemp[i + headIdx - Coder.PROTOCOL_HEAD_COUNT]; // } //} Coder.DecodeData(byteHead, ref dataInfo); if (!ReadBuffer(ns, dataInfo.contentLen, dataInfo.Content)) { db.InsertErrorInfo(enumSystemErrorCode.TcpRecieveErr, null, "数据主体读取超时", byteHead); return(result); } result = true; return(result); }
/// <summary> /// 基本格式解码 /// </summary> /// <param name="buff"></param> /// <returns></returns> public static NetStructure.NormalDataStruct DecodeData(byte[] buff, ref NetStructure.NormalDataStruct data) { int locIdx = 4; data.FactoryNumber = ConvertHelper.BytesToInt32(buff, 0, true); data.Code = (enumCommandType)ConvertHelper.BytesToInt16(buff, locIdx, true); locIdx += 2; data.contentLen = ConvertHelper.BytesToInt32(buff, locIdx, true); locIdx += 4; data.FillField = ConvertHelper.BytesToInt16(buff, locIdx, true); locIdx += 2; data.Content = new byte[data.contentLen]; return(data); }
/// <summary> /// 基本格式编码 /// </summary> /// <param name="data"></param> /// <param name="buff"></param> private static void EncodeData(NetStructure.NormalDataStruct data, out byte[] buff) { buff = new byte[data.contentLen + 12]; byte[] magicByte = ConvertHelper.Int32ToBytes(FACTORY_NORMAL, true); Array.Copy(magicByte, buff, 4); byte[] cmdByte = ConvertHelper.Int16ToBytes((Int16)data.Code, true); Array.Copy(cmdByte, 0, buff, 4, 2); byte[] conLenByte = ConvertHelper.Int32ToBytes(data.contentLen, true); Array.Copy(conLenByte, 0, buff, 6, 4); int randInfo = new Random().Next(0, 0xFFFF); byte[] randInfoByte = ConvertHelper.Int16ToBytes(randInfo, true); Array.Copy(randInfoByte, 0, buff, 10, 2); if (data.Content != null) { Array.Copy(data.Content, 0, buff, 12, data.contentLen); } }
private static void HandlerByProtocol(ref NetStructure.NormalDataStruct dataInfo) { try { interfaceClientHanlder clientHandler = GetHandlerByCommand(dataInfo.Code); if (clientHandler == null) { db.InsertErrorInfo(enumSystemErrorCode.TcpDefaultHandlerErr, null, dataInfo.IpAddress, dataInfo.Content); return; } byte[] byteResult = clientHandler.HandlerClientData(dataInfo.Content); //返回信息 byte[] buffResp = null; if (clientHandler.ShouldResponse()) { Coder.EncodeServerResp(dataInfo.Code + 1, byteResult, out buffResp); dataInfo.stream.Write(buffResp, 0, buffResp.Length); } int tempMachineId = dataInfo.Code == enumCommandType.UP_DEVICE_SETTING_SEND ? ConvertHelper.BytesToInt16(buffResp, buffResp.Length - 2, true) : //设置协议没有设备ID,所以用返回回去的ID ConvertHelper.BytesToInt16(dataInfo.Content, true); //其它协议以设备ID开头 dataInfo.MachineId = tempMachineId; if (netConnection.ContainsKey(tempMachineId)) { netConnection[tempMachineId] = dataInfo.stream; } else { netConnection.Add(tempMachineId, dataInfo.stream); } } catch (Exception ex) { db.InsertErrorInfo(enumSystemErrorCode.TcpHandlerException, ex, dataInfo.IpAddress, dataInfo.Content); } }
/// <summary> /// 施工单操作编码 /// </summary> /// <param name="schedule"></param> /// <param name="buff"></param> public static void EncodeScheHandler(Schedules schedule, enumCommandType command, out byte[] buff) { byte[] content = new byte[1024]; int locIdx = 0, tempLen = 2; //机器码 byte[] machineBytes = ConvertHelper.Int16ToBytes(schedule.MachineId, true); Array.Copy(machineBytes, content, tempLen); locIdx += tempLen; //施工单编号 byte[] numberBytes = Encoding.ASCII.GetBytes(schedule.Number); tempLen = numberBytes.Length; content[locIdx++] = (byte)tempLen; Array.Copy(numberBytes, 0, content, locIdx, tempLen); locIdx += tempLen; NetStructure.NormalDataStruct data = new NetStructure.NormalDataStruct() { Code = command, contentLen = locIdx, Content = content }; EncodeData(data, out buff); }