异常连接协议的 Xml 序列化
在我的应用程序中,我有一个 PacketList
类和 Packet
类。我希望能够使用 PacketList
上的序列化助手来得到所需的输出,但不知道该往哪个方向走。
我正在编写一个程序来模仿服务器它有一个特殊的协议来发送数据。
客户端发送格式为:COMMAND|ARGUMENT_0|ARGUMENT_1|ARGUMENT_2|...|ARGUMENT_N\0
的数据。其中 COMMAND
可以是 MOVE
或 LOGIN
之类的内容。
服务器将以以下格式响应:
<p c='COUNT'>
<m p='N' p0='COMMAND_0' p1='ARUGMENT_0' ... pN='ARGUMENT_N'/>
<m p='N' p0='COMMAND_1' p1='ARUGMENT_0' ... pN='ARGUMENT_N'/>
<m p='N' p0='COMMAND_2' p1='ARUGMENT_0' ... pN='ARGUMENT_N'/>
<m p='N' p0='COMMAND_3' p1='ARUGMENT_0' ... pN='ARGUMENT_N'/>
...
<m p='N' p0='COMMAND_COUNT' p1='ARUGMENT_0' ... pN='ARGUMENT_N'/>
</p>
其中 COMMAND_0
可能类似于 UPDATE_POSITION
或 AUTHENTICATED
。
是的,这是一种愚蠢的做事方式。不,我不知道为什么要这样做。不,我无法改变它。
无论如何,我希望模拟服务器将数据包发送回客户端的方式。到目前为止我得到的是:
XmlWriterSettings _Settings = new XmlWriterSettings {
OmitXmlDeclaration = true,
Indent = true
};
StringBuilder _Xml = new StringBuilder();
XmlWriter _Writer = XmlWriter.Create(_Xml, _Settings);
_Writer.WriteStartElement("p");
_Writer.WriteAttributeString("c", "1");
_Writer.WriteStartElement("m");
_Writer.WriteAttributeString("p", "2");
_Writer.WriteAttributeString("p0", "COMMAND");
_Writer.WriteAttributeString("p1", "ARGUMENT_0");
_Writer.WriteAttributeString("p2", "ARGUMENT_1");
_Writer.WriteEndElement(); // </m>
_Writer.WriteEndElement(); // </p>
_Writer.Flush();
Console.WriteLine(_Xml.ToString());
这工作正常并输出:
<p c="1">
<m p="2" p0="COMMAND" p1="ARGUMENT_0" p2="ARGUMENT_1" />
</p>
但是,我想以更干净的方式实现它。
我的 PacketList 基本上包含一个 Packet 列表,而 Packet 包含一个 String _Command 和 String[ ]_参数。
如果有人能指导我正确的方向,我将不胜感激。
In my application I have a PacketList
class and Packet
class. I'd like to be able to use the serialization helpers on PacketList
to come up with something like the desired output, but have no idea what direction to go in.
I am writing a program to imitate a server which has a peculiar protocol for sending data.
Client sends data with format: COMMAND|ARGUMENT_0|ARGUMENT_1|ARGUMENT_2|...|ARGUMENT_N\0
. Where COMMAND
could be something like MOVE
or LOGIN
.
The server would respond in the format:
<p c='COUNT'>
<m p='N' p0='COMMAND_0' p1='ARUGMENT_0' ... pN='ARGUMENT_N'/>
<m p='N' p0='COMMAND_1' p1='ARUGMENT_0' ... pN='ARGUMENT_N'/>
<m p='N' p0='COMMAND_2' p1='ARUGMENT_0' ... pN='ARGUMENT_N'/>
<m p='N' p0='COMMAND_3' p1='ARUGMENT_0' ... pN='ARGUMENT_N'/>
...
<m p='N' p0='COMMAND_COUNT' p1='ARUGMENT_0' ... pN='ARGUMENT_N'/>
</p>
Where COMMAND_0
could be something like UPDATE_POSITION
or AUTHENTICATED
.
Yes, this is a silly way of doing things. No, I don't know why it's done this way. No, I can't change it.
Anyways, I am looking to emulate the way that the server sends the packet back to the client. What I have gotten so far is:
XmlWriterSettings _Settings = new XmlWriterSettings {
OmitXmlDeclaration = true,
Indent = true
};
StringBuilder _Xml = new StringBuilder();
XmlWriter _Writer = XmlWriter.Create(_Xml, _Settings);
_Writer.WriteStartElement("p");
_Writer.WriteAttributeString("c", "1");
_Writer.WriteStartElement("m");
_Writer.WriteAttributeString("p", "2");
_Writer.WriteAttributeString("p0", "COMMAND");
_Writer.WriteAttributeString("p1", "ARGUMENT_0");
_Writer.WriteAttributeString("p2", "ARGUMENT_1");
_Writer.WriteEndElement(); // </m>
_Writer.WriteEndElement(); // </p>
_Writer.Flush();
Console.WriteLine(_Xml.ToString());
This works properly and outputs:
<p c="1">
<m p="2" p0="COMMAND" p1="ARGUMENT_0" p2="ARGUMENT_1" />
</p>
However, I'd like to implement this in a cleaner way.
My PacketList
basically contains a list of Packet
s, and Packet
contains a String _Command
and String[] _Arguments
.
If anyone could guide me in the right direction it would be much appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
你现在的做法是最好的。我想说使用 XmlSerializer 并使用适当的 Xml*Attribute 属性来装饰 Packet 和 PacketList 类的属性,以控制输出的格式设置方式,但由于您需要编写与集合(p0、p1、p2 等)相对应的属性.) 这是行不通的。
由于您需要编写如此奇怪的格式,因此按照当前的方式手动编写它是有意义的。
安德鲁
The way you are currently doing it is the best. I would say to use the XmlSerializer and decorate your Packet and PacketList class's properties with the appropriate Xml*Attribute attributes to control the way the output is formatted, but since you need to write attributes corresponding to a collection (p0, p1, p2, etc.) this will not work.
Since you need to write such a weird format, it makes sense to write it manually the way you currently are.
Andrew
我赞同安德鲁的回答。
AFAIK,除非您编写自己的序列化程序,否则无法做到这一点,因为您在单个 XML 元素中将两级数据元素(具有动态数量的元素!)组合为属性。这样做是没有意义的,而且,XmlSerializer 需要一些意义才能仅使用反射来工作。
I second Andrew's answer.
AFAIK, there's no way to do it unless you write your own serializer, since you compose two levels of data elements (with dynamic number of elements!) as attributes in a single XML element. There's no sense doing it, and, well, XmlSerializer needs some sense in order to work using just Reflection.