/// <summary> /// UDP接続 /// </summary> /// <param name="ipAddress"></param> /// <param name="portNo"></param> /// <returns></returns> public bool Connect(string ipAddress, int portNo) { bool ret = false; try { if (this._IsConnected == false) { this._udpClientSend.Connect(ipAddress, portNo); this._IpAddress = ipAddress; this._PortNo = (UInt16)portNo; this._IsConnected = true; this._SendSeqNo = 0; SendLinkMessage(); ret = true; } } catch (Exception ex) { MoCsLog.WriteLog(String.Format(@"UDP接続異常({0}/{1})" , ipAddress , portNo) + ":" + ex.Message); } return(ret); }
/// <summary> /// メッセージ送信 /// </summary> /// <param name="message"></param> /// <returns></returns> public bool SendMessage(string message, UInt16 seqNo) { bool ret = false; string packet; // シーケンス番号作成 string seqFormat = String.Format("D{0}", c_PacketSeqNoSize); string strSeqData = seqNo.ToString(seqFormat); // ボディ作成 byte[] msgData = Encoding.UTF8.GetBytes(message); // パケット長作成 string lenFormat = String.Format("D{0}", c_PacketLenSize); // パケット長CRC作成 int length = msgData.Length; string strLenCrc; string strLenData = length.ToString(lenFormat); byte[] crcData = Encoding.UTF8.GetBytes(strSeqData + strLenData); strLenCrc = Crc16.GetCrc(crcData, crcData.Length).ToString("X4"); // ボディCRC作成 string strBodyCrc; strBodyCrc = Crc16.GetCrc(msgData, msgData.Length).ToString("X4"); // パケット作成 packet = c_PacketHeader + strSeqData + strLenData + strLenCrc + message + strBodyCrc + c_PacketFooter; // 送信 try { if (this._udpClientSend != null && this._IsConnected == true) { byte[] data = Encoding.UTF8.GetBytes(packet); this._udpClientSend.Send(data, data.Length); ret = true; } } catch (Exception ex) { MoCsLog.WriteLog(String.Format(@"UDP送信異常({0}/{1})" , this.IpAddress , this.PortNo) + ":" + ex.Message); throw ex; } return(ret); }
/// <summary> /// UDP切断 /// </summary> public void Disconnect() { //ポートクローズ try { this._udpClientSend.Close(); this._udpClientRecv.Close(); this._IsConnected = false; } catch (Exception ex) { MoCsLog.WriteLog(String.Format(@"UDP切断異常({0}/{1})" , this.IpAddress , this.PortNo) + ":" + ex.Message); } }
/// <summary> /// メッセージ受信ループ /// </summary> private void threadFuncRecvMsgLoop() { while (bRecvMsgContinue) { try { // 受信処理 // パケット受信待ち(ブロッキング) string message; if (true == comCl.RecvMessage(out message)) { string[] parseMsg = message.Split(CellMonTabMessage.Delim); if (parseMsg[0] == CellMonTabMessage.CmdGet || parseMsg[0] == CellMonTabMessage.CmdPut) { // 要求メッセージ受信 if (GetMessageMonTabSim(parseMsg[0], parseMsg[1], out this.curRecvMsg)) { // メッセージクラスに受信メッセージ設定 this.curRecvMsg.MessageData = message; // 受信メッセージ展開 this.curRecvMsg.ParsePacket(); // 受信シーケンス番号をメッセージ内に保存 this.curRecvMsg.SequenceNo = comCl.RecvSeqNo; // 受信メッセージバッファ書込み if (true != this.recvMessageBuf.TryAdd(this.curRecvMsg)) { } else { // コマンド受信コールバック NotifyReceivedMessageEvent(this.curRecvMsg); } // 受信メッセージ削除 this.curRecvMsg = null; } } else if (parseMsg[0] == CellMonTabMessage.ResOk || parseMsg[0] == CellMonTabMessage.ResNg) { // 送信メッセージセージのシーケンス番号化チェックする if (comCl.SendSeqNo == comCl.RecvSeqNo) { lock (objSendRecvLock) { // 正常応答受信 if (this.curSendMsg != null) { if (this.curSendMsg.SubCmdName == parseMsg[1]) { if (GetResMessageMonTabSim(this.curSendMsg, out this.curRecvMsg)) { // メッセージ応答クラスに受信メッセージ応答設定 this.curRecvMsg.MessageData = message; // 受信メッセージ応答展開 this.curRecvMsg.ParsePacket(); // メッセージ送信状態更新(応答受信) this.curSendMsg.SendStatus = CellMonTabMessage.eSendStatus.RecvRes; // 応答受信コールバック this.NotifySentMessageEvent(this.curSendMsg, this.curRecvMsg); // 送信メッセージ削除 this.curSendMsg = null; this.curRecvMsg = null; // 再送タイマー停止 StopSendRetryTimer(); // 再送回数リセット this.SendRetryNum = 0; // 次の送信メッセージがあれば送信イベント設定 if (this.sendMessageBuf.Count != 0) { this.eventSendProc[(int)eEventSendProc.ReqSend].Set(); } // 送信メッセージのシーケンス番号を更新する comCl.SendSeqNo++; } } } } } } } } catch (Exception ex) { bRecvMsgContinue = false; } } this.comCl.Disconnect(); MoCsLog.WriteLog(String.Format(@"監視モニタ、タブレット受信処理終了")); }
/// <summary> /// メッセージ送信ループ /// </summary> private void threadFuncSendMsgLoop() { int ret = -1; while (bSendMsgContinue) { try { // 送信処理 // イベントメッセージ処理 ret = WaitHandle.WaitAny(this.waitHndlSendProc, -1, false); lock (objSendRecvLock) { if (ret == EventWaitHandle.WaitTimeout) { } if (true == this.eventSendProc[(int)eEventSendProc.ReqSendRes].WaitOne(0)) { this.eventSendProc[(int)eEventSendProc.ReqSendRes].Reset(); // メッセージ応答送信 CellMonTabMessage sendMsgRes; // 送信メッセージバッファ読出し if (true == this.sendMessageResBuf.TryTake(out sendMsgRes)) { // メッセージ作成 sendMsgRes.MakePacket(); // メッセージ送信 this.comCl.SendMessageRes(sendMsgRes.MessageData, sendMsgRes.SequenceNo); // メッセージ送信状態更新(送信済み) sendMsgRes.SendStatus = CellMonTabMessage.eSendStatus.Sent; } // 応答送信メッセージバッファに // メッセージがあれば送信する if (this.sendMessageResBuf.Count > 0) { this.eventSendProc[(int)eEventSendProc.ReqSendRes].Set(); } } if (true == this.eventSendProc[(int)eEventSendProc.ReqSend].WaitOne(0)) { this.eventSendProc[(int)eEventSendProc.ReqSend].Reset(); // メッセージ送信 if (this.curSendMsg == null) { CellMonTabMessage sendMsg; // 送信メッセージバッファ読出し if (true == this.sendMessageBuf.TryTake(out sendMsg)) { this.curSendMsg = sendMsg; // メッセージ作成 this.curSendMsg.MakePacket(); // メッセージ送信 this.comCl.SendMessage(this.curSendMsg.MessageData); // メッセージ送信状態更新(送信済み) this.curSendMsg.SendStatus = CellMonTabMessage.eSendStatus.Sent; // 再送タイマー開始 StartSendRetryTimer(); } } } if (true == this.eventSendProc[(int)eEventSendProc.ReqSendRetry].WaitOne(0)) { this.eventSendProc[(int)eEventSendProc.ReqSendRetry].Reset(); // メッセージ再送 if (this.curSendMsg != null) { this.comCl.SendMessage(this.curSendMsg.MessageData); // 再送タイマー開始 StartSendRetryTimer(); } } if (true == this.eventSendProc[(int)eEventSendProc.SendFail].WaitOne(0)) { this.eventSendProc[(int)eEventSendProc.SendFail].Reset(); // メッセージ送信状態更新(送信失敗) this.curSendMsg.SendStatus = CellMonTabMessage.eSendStatus.SendNg; // 送信失敗コールバック NotifySendMessageFialEvent(this.curSendMsg); // メッセージ送信失敗 this.curSendMsg = null; this.SendRetryNum = 0; // 再送タイマー停止 StopSendRetryTimer(); // 次の送信メッセージがあれば送信イベント設定 if (this.sendMessageBuf.Count != 0) { this.eventSendProc[(int)eEventSendProc.ReqSend].Set(); } // 送信メッセージのシーケンス番号を更新する comCl.SendSeqNo++; Console.WriteLine("?????監視モニタ、タブレット送信失敗?????"); } } } catch (Exception ex) { StopSendRetryTimer(); bSendMsgContinue = false; } } this.comCl.Disconnect(); MoCsLog.WriteLog(String.Format(@"監視モニタ、タブレット送信処理終了")); }
/// <summary> /// メッセージ受信 /// </summary> /// <param name="packet">パケット</param> /// <returns>ボディ部</returns> public bool RecvMessage(out string recvPacket) { bool ret = false; // int res = -1; recvPacket = ""; try { // 受信 if (this._udpClientRecv != null && this._IsConnected == true) { string packet; byte[] data = null; bool bReceived = false; do { // UDPデータ受信 if (this.recvDataBuf.Count == 0 || this.rcvPktStatus != ePacketStatus.SEARCH_HEADER || (this.rcvPktStatus == ePacketStatus.SEARCH_HEADER && this.recvDataBuf.Count < c_PacketHeader.Length)) { IPEndPoint rtIpEndPoint = null; data = this._udpClientRecv.Receive(ref rtIpEndPoint); } // 受信データからパケット取得 if (data != null && data.Count() > 0 && true == GetRecvPacket(data, data.Count(), out packet)) { // 受信パケットからボディ部を抜き出す int headLen = c_PacketHeader.Length + c_PacketSeqNoSize + c_PacketLenSize + c_PacketLenCrcSize; int bodyLen = packet.Length - headLen - c_PacketBodyCrcSize - c_PacketFooter.Length; if (bodyLen == 0) { UInt32 serNo = Convert.ToUInt32(packet.Substring(c_PacketHeader.Length, c_PacketSeqNoSize)); if (serNo == 0) { this._RecvSeqNo = 0; } } else { recvPacket = packet.Substring(headLen, bodyLen); ret = true; bReceived = true; } } } while (!bReceived); } } catch (Exception ex) { MoCsLog.WriteLog(String.Format(@"UDP受信異常({0}/{1})" , this.IpAddress , this.PortNo) + ":" + ex.Message); throw ex; } return(ret); }