[英]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.