/// <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> /// 受信データからパケットを取り出す /// </summary> /// <param name="recvData">受信データ</param> /// <param name="dataLen">受信データ長</param> /// <param name="recvPacket">受信パケット出力</param> /// <returns>パケット有無</returns> private bool GetRecvPacket(byte[] recvData, int dataLen, out string recvPacket) { bool ret = false; ePacketStatus preStatus; recvPacket = ""; // 受信データを一時バッファへ保存 for (int cnt = 0; cnt < dataLen; cnt++) { recvDataBuf.Enqueue(recvData[cnt]); } // パケット受信処理初期化 if (this.rcvPktStatus == ePacketStatus.NONE || this.rcvPktStatus == ePacketStatus.INIT) { this.recvPacketLen = 0; this.rcvPktStatus = ePacketStatus.SEARCH_HEADER; } do { preStatus = this.rcvPktStatus; switch (this.rcvPktStatus) { case ePacketStatus.SEARCH_HEADER: if (this.recvDataBuf.Count >= c_PacketHeader.Length) { string header = Encoding.UTF8.GetString(this.recvDataBuf.Take(c_PacketHeader.Length).ToArray()); if (header != c_PacketHeader) { // ヘッダー不一致 this.recvDataBuf.Dequeue(); } else { // ヘッダー一致 this.rcvPktStatus = ePacketStatus.GET_HEADE_INFO; } } break; case ePacketStatus.GET_HEADE_INFO: if (this.recvDataBuf.Count >= (c_PacketHeader.Length + c_PacketSeqNoSize + c_PacketLenSize + c_PacketLenCrcSize)) { // シーケンス番号取得 IEnumerable <byte> seqData = this.recvDataBuf.Skip(c_PacketHeader.Length).Take(c_PacketSeqNoSize); // パケット長取得 IEnumerable <byte> lenData = this.recvDataBuf.Skip(c_PacketHeader.Length + c_PacketSeqNoSize).Take(c_PacketLenSize); // CRCチェック(ヘッダー、シーケンス番号、データ長) string strCrc = Encoding.UTF8.GetString(this.recvDataBuf.Skip(c_PacketHeader.Length + c_PacketSeqNoSize + c_PacketLenSize).Take(c_PacketLenCrcSize).ToArray()); UInt16 pktCrc = Convert.ToUInt16(strCrc, 16); IEnumerable <byte> crcData = this.recvDataBuf.Skip(c_PacketHeader.Length).Take(c_PacketSeqNoSize + c_PacketLenSize); UInt16 calCrc = Crc16.GetCrc(crcData.ToArray(), c_PacketSeqNoSize + c_PacketLenSize); if (pktCrc != calCrc) { // データ長CRC不一致 this.recvDataBuf.Dequeue(); // ヘッダー探索へ this.rcvPktStatus = ePacketStatus.SEARCH_HEADER; } else { // データ長CRC一致 // 受信シーケンス番号更新 this._RecvSeqNo = Convert.ToUInt16(Encoding.UTF8.GetString(seqData.ToArray())); Console.WriteLine("rseqno={0}", this._RecvSeqNo); // 受信パケット長更新 this.recvPacketLen = Convert.ToInt32(Encoding.UTF8.GetString(lenData.ToArray())); // ボディ、CRC、フッター受信へ this.rcvPktStatus = ePacketStatus.GET_BODY_CRC_FOOTER; } } break; case ePacketStatus.GET_BODY_CRC_FOOTER: if (this.recvDataBuf.Count >= (c_PacketHeader.Length + c_PacketSeqNoSize + c_PacketLenSize + c_PacketLenCrcSize + this.recvPacketLen + c_PacketBodyCrcSize + c_PacketFooter.Length)) { string footer = Encoding.UTF8.GetString(this.recvDataBuf.Skip(c_PacketHeader.Length + c_PacketSeqNoSize + c_PacketLenSize + c_PacketLenCrcSize + this.recvPacketLen + c_PacketBodyCrcSize).Take(c_PacketFooter.Length).ToArray()); if (footer != c_PacketFooter) { // フッター不一致 this.recvDataBuf.Dequeue(); // ヘッダー探索 this.rcvPktStatus = ePacketStatus.SEARCH_HEADER; } else { // フッター一致 // CRCチェック // ボディ取得 IEnumerable <byte> bodyData = this.recvDataBuf.Skip(c_PacketHeader.Length + c_PacketSeqNoSize + c_PacketLenSize + c_PacketLenCrcSize).Take(this.recvPacketLen); // CRCチェック string strCrc = Encoding.UTF8.GetString(this.recvDataBuf.Skip(c_PacketHeader.Length + c_PacketSeqNoSize + c_PacketLenSize + c_PacketLenCrcSize + this.recvPacketLen).Take(c_PacketBodyCrcSize).ToArray()); UInt16 pktCrc = Convert.ToUInt16(strCrc, 16); UInt16 calCrc = Crc16.GetCrc(bodyData.ToArray(), this.recvPacketLen); if (pktCrc != calCrc) { // ボディCRC不一致 this.recvDataBuf.Dequeue(); // ヘッダー探索 this.rcvPktStatus = ePacketStatus.SEARCH_HEADER; } else { // ボディCRC一致 this.rcvPktStatus = ePacketStatus.PACKET_RECEIVED; } } } break; case ePacketStatus.PACKET_RECEIVED: // 受信パケット保存 int pktLen = c_PacketHeader.Length + c_PacketSeqNoSize + c_PacketLenSize + c_PacketLenCrcSize + this.recvPacketLen + c_PacketBodyCrcSize + c_PacketFooter.Length; recvPacket = Encoding.UTF8.GetString(this.recvDataBuf.Take(pktLen).ToArray()); // パケット分の受信データ取り出し for (int cnt = 0; cnt < pktLen; cnt++) { this.recvDataBuf.Dequeue(); } this.rcvPktStatus = ePacketStatus.SEARCH_HEADER; ret = true; break; default: break; } } while (((preStatus != this.rcvPktStatus) || (this.rcvPktStatus == ePacketStatus.SEARCH_HEADER && this.recvDataBuf.Count >= c_PacketHeader.Length)) && ret == false); return(ret); }