C#のソケット通信、メッセージ定義長の同期受信データ

何のアップロードファイルが存在しないので、何も大きなバイトが送信されない、データがキューに来ると、そのデータを受信するために何の非同期、同期の使用はありません。

原理は次のとおりです。

メッセージヘッダの1.最初の4つのバイトは、メッセージ本体の長さを定義しました。

2.定義するメッセージのボディバイト以下。

3.サーバは、メッセージ、メッセージ本体の長さに応じて得られたメッセージヘッダマークを受け、そうでない場合、受信し続け、十分と過剰が存在する場合、ヘッドが順次ダウン再度取得します。

        プライベート 無効受信(ソケットソケット、文字列のIP)
        {
            Task.Factory.StartNew(() =>
            {
                 =パックBytePkg();

                しばらく
                {
                    試します
                    {
                        // ソケットが切断された場合には、サイクルの終わり
                        IF(!Socket.Connected)
                        {
                            _logger.Warn($ " IP:IP {}、ソケットが切断された、データの受信を停止し; " );
                             BREAK 
                        }

                        バイト [] prevBytes = 新しい バイト [ 1024 ];
                        INT LEN = socket.Receive(prevBytes、prevBytes.Length、SocketFlags.None)。
                        VARバイト= prevBytes.Take(LEN).ToArray();

                        この.RcvHeadData(パック、バイト);
                    }
                    キャッチ(例外の例)
                    {
                        _logger.Error($ " IP:IP {}、受信されたデータである異常なソケット、メッセージ:ex.Message {}、スタックトレース:ex.StackTrace {}; " );
                    }
                }
            });
        }
        
        ///  <要約> 
        /// 消息头
         ///  </要約> 
        ///  <PARAM NAME = "パック"> </ param>の
        ///  <PARAM NAME = "バイト"> </ param>の
        プライベート のボイド RcvHeadData(BytePkgパック、バイト[]バイト)
        {
            VAR LEN = bytes.Length。

            pack.headIndex + = LEN。もし(pack.headIndex < pack.headLen)
            { ためのint型のx = 0のx ++; X <LEN 
                {
                    pack.headBuff [pack.headIndex - LEN + X] = バイト[X]。
                }。
            }
            
            { VAR actualHeadLen = pack.headIndex -でlen; // 実際の長さのヘッド
                VAR skipHeadLen = pack.headLen - actualHeadLen; //は、長さを作るために必要があり、ヘッドの長さを定義する-実際の長さのヘッドが必要=体長はスキップ
                のためにINT X = 0 ; X <skipHeadLen; X ++ 
                {
                    pack.headBuff [actualHeadLen + X] = バイト[X]。
                } // ★★★★★メッセージ処理部★★★★★開始
                VAR bodyLen = LENを; // 本体の長さ
                IF(skipHeadLen> 0 
                { 
                    BodyLen = LEN - skipHeadLen; // 第一の残りの部分の長さを取得 
                    pack.InitBodyBuffを(); // 初めて体を初期化するために必要
                } この.RcvBodyData(パック、bytes.Skip(skipHeadLen).Takeを(bodyLen ).toArray())。
            }
        }

        ///  <要約> 
        /// 消息体
         ///  </要約> 
        ///  <PARAM NAME = "パック"> </ param>の
        ///  <PARAM NAME = "バイト"> </ param>の
        プライベート のボイド RcvBodyData(BytePkgパック、バイト[]バイト)
        {
            VAR LEN = bytes.Length。

            pack.bodyIndex + = LEN。
もし(pack.bodyIndex < pack.bodyLen)
            { ためのint型のx = 0のx ++; X <LEN 
                {
                    pack.bodyBuff [pack.bodyIndex - LEN + X] = バイト[X]。
                }。
            }
            
            { VAR ; lenの- actualBodyLen = pack.bodyIndex // 本体の実際の長さ
                VAR skipBodyLen = pack.bodyLen - actualBodyLen; // 充填する必要の長さは、本体は、長さ定義-体の実際の長さ=ボディの長さが得られます
                INT X = 0 ; X <skipBodyLen; X ++ 
                {
                    pack.bodyBuff [actualBodyLen + X] = バイト[X]。
                }
// 受信データ処理 
                NetMsg ByteHelper.DeSerialize MSG = <NetMsg> (pack.bodyBuff);
                 この.OnReceiveMsg(MSG);
 // リセットパケット
                pack.ResetDataは(); // ★★★★★プロセスを開始メッセージヘッダ部★★★★★ 
                この.RcvHeadData(パック、bytes.Skip(skipBodyLen).toArray())。
            }
        }

あなたが信頼していない場合は、コードが正しい観察論理的、場所プラスログにログを追加することができます。説明:これはPESocket改革と呼ばれるオープンソースプロジェクト、の図です。

おすすめ

転載: www.cnblogs.com/subendong/p/12570289.html