繁体   English   中英

如何根据类型将传入数据包拆分

[英]How to split incoming packet in according to it's type

我正在运行服务器,并且正在从客户端接收以下消息

string message=2001 24 9228 2323385135 202 Name Account 25.97.64.180 1_66_123 - - - -3001 24 302 Name RECEIVERNAME Account 1_151_122 hello6001 24 Name Account 165 3103069 6353069 575839004 602

我如何拆分此消息以获得单独的消息,如

string message1=2001 24 9228 2323385135 202 Name Account 25.97.64.180 1_66_123 - - - -(it always contains 13 strings)
string message2=3001 24 302 Name RECEIVERNAME Account 1_151_122 hello (it always contains 8 strings)
string message3=6001 24 Name Account 165 3103069 6353069 575839004 602(it always contain 9 strings)

作为其服务器,一直很难获得单独的消息,有什么解决方案吗?

到目前为止,我在一个数据包中处理相同类型消息的代码。

   string data=2001 24 0 0 210 Name Account 124.123.100.99 61_60_85 name account 124.123.100.99 2116653670_02001 24 9646 1053821743 207 name account25.97.64.180 1_149_128 TorrBier - - - 

          string Packet_Type = data.Substring(0, 4);

            string[] Packet_Split = Regex.Split(data, Packet_Type + " 24 ");

            List<string> Seperate_Packets = new List<string>();


            foreach (string packetstrings in Packet_Split)
            {

                if (packetstrings.Trim().Length > 0)
                    Seperate_Packets.Add(Packet_Type + " 24 " + "" + packetstrings.Trim());

            }

我将24作为分割参数添加为数据包中的一些数字可能包含2001/3001,因此

string split="2001 24 ";

有助于正确区分不同类型的消息

有关更多信息,这就是数据包的含义

2001 24 0 0 210 Name Account 25.97.64.180 1_155_126 Name Account 25.97.64.180 3722785844_1000
                    /// 
                    /// Part 1 : 2001 Packet Type
                    /// Part 2 : 24 Server ID
                    /// Part 3 : Item Code
                    /// Part 4 : Uniq number
                    /// Part 5 : Action Type - IMP
                    /// Part 6 : Actor Character Name
                    /// Part 7 : Actor Character Account
                    /// Part 8 : Actor IP Address
                    /// Part 9 : Actor Location
                    /// Part 10 : Receiver Character name  / NPC Name
                    /// Part 11: Receiver Account
                    /// Part 12: Receiver IP Address
                    /// Part 13: Item OPTIONS DETAILS

每个数据包的此模式都不同

我很快写了它,但没有对其进行优化。 很多重复的代码。 无论如何,即使没有完全测试它也可以。 以此作为基本起点。

PS您可以通过在正确的位置添加som TrimStart()来增强它。

    public static IList<string> Parser(string srvString)
    {
        IList<string> list = new List<string>();

        while (!string.IsNullOrWhiteSpace(srvString))
        {
            string[] split = srvString.Split();
            string code = srvString.Split()[0];
            switch (code)
            {
                case "2001":
                    int i = 13;
                    if (i >= split.Length)
                    {
                        // we are a the end of the server message
                        list.Add(srvString);
                        srvString = null;
                    }
                    else
                    {
                        string last = split[i - 1];
                        Match match = Regex.Match(last, "(2001|3001|6001)");
                        if (!match.Success) throw new Exception("Parsing error");
                        string msg = srvString.Substring(0, srvString.IndexOf(last, code.Length) + last.Length - 4);
                        list.Add(msg);
                        srvString = srvString.Substring(msg.Length);
                    }
                    break;

                case "3001":
                    i = 8;
                    if (i >= split.Length)
                    {
                        // we are a the end of the server message
                        list.Add(srvString);
                        srvString = null;
                    }
                    else
                    {
                        string last = split[i - 1];
                        Match match = Regex.Match(last, "(2001|3001|6001)");
                        if (!match.Success) throw new Exception("Parsing error");
                        string msg = srvString.Substring(0, srvString.IndexOf(last, code.Length) + last.Length - 4);
                        list.Add(msg);
                        srvString = srvString.Substring(msg.Length);
                    }
                    break;

                case "6001":
                    i = 9;
                    if (i >= split.Length)
                    {
                        // we are a the end of the server message
                        list.Add(srvString);
                        srvString = null;
                    }
                    else
                    {
                        string last = split[i - 1];
                        Match match = Regex.Match(last, "(2001|3001|6001)");
                        if (!match.Success) throw new Exception("Parsing error");
                        string msg = srvString.Substring(0, srvString.IndexOf(last, code.Length) + last.Length - 4);
                        list.Add(msg);
                        srvString = srvString.Substring(msg.Length);
                    }
                    break;

                default:
                    throw new Exception("Unkown message code: " + code);

            }   // switch

        }   // while...

        // return the list
        return list;
    }

每个消息的第一部分(2001、3001、6001)都可以用作消息类型的标识符。 当您确定消息类型时,您知道要形成一条消息还要使用多少个字符串。

假设消息块始终以相同数量的字符串和相同顺序出现,尽管它可能不是最优雅的解决方案,但您可以将空格分成列表或数组,并使用stringbuilder创建消息,例如

for(int i=0; i<message.length;i++)
{
   if(i>=0 && < 13){ [populate message 1]; }
   if(i>=13 && < 21){ [populate message 2]; }
   if(i>=21 && < message.length){ [populate message 3]; }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM