我使用Lidgren.Networking在客户机/服务器架构中在服务器和客户端之间发送数据。我已经创建了一个数据包类,以便在通过网络发送数据包时使用。
Packet.cs
public abstract class Packet : IPackable
{
public abstract void PackIntoNetMessage(NetOutgoingMessage msg);
public abstract void PopulateFromNetMessage(NetIncomingMessage msg);
}IPackable.cs
interface IPackable
{
void PackIntoNetMessage(NetOutgoingMessage msg);
void PopulateFromNetMessage(NetIncomingMessage msg);
}然后,我有应用程序特定的包类,如下所示
public class PositionPacket : Packet
{
public int PosX { get; set; }
public int PosY { get; set; }
public override void PackIntoNetMessage(NetOutgoingMessage m)
{
m.Write((byte)Networking.PacketTypes.PositionPacket);
m.Write(PosX);
m.Write(PosY);
}
public override void PopulateFromNetMessage(NetIncomingMessage m)
{
PosX = m.ReadInt32();
PosY = m.ReadInt32();
}
}发送数据包很容易,我只需创建一个数据包和PackIntoNetMessage(msg),然后发送它。但是当我试图接收数据包时,我遇到了一些恼人的结构问题。
我从读取第一个字节开始
var packetType = (Networking.PacketTypes)incomingMsg.ReadByte();但是,为了得到正确的构造函数,我必须为每种数据包类型设置一个大小写。
switch (packetType)
{
case Networking.PacketTypes.PositionPacket:
incPacket = new Packets.PositionPacket();
break;
default:
incPacket = null;
break;
}
//Populate packet from net message
incPacket.PopulateFromNetMessage(incomingMsg);这是我不喜欢的。我希望能够制作一个通用的数据包处理系统来处理来自数据包的任何类。我想反思不是一个好主意,因为它会扼杀表演。我该如何构造它以使它更加通用呢?
发布于 2014-08-04 09:54:27
需要以某种方式创建特定类的实例,这样您就可以在启动时使用反射来填充字典中从它们的ids存储的数据包派生出来的所有可用类。
然后,创建一个实例可以归结为:
var packetTypeId = (Networking.PacketTypes)incomingMsg.ReadByte();
var incPackage = (Package)Activator.CreateInstance(packetTypes[packetTypeId]);如果您担心创建许多实例并期望垃圾收集周期对应用程序的速度产生很大影响,那么您可以创建一个回收实例的对象池。只要将不再使用的对象放到池中,就可以防止GC循环。
var packetTypeId = (Networking.PacketTypes)incomingMsg.ReadByte();
Type packetType = packetTypes[packetTypeId];
Package incPackage;
if(!pool.TryGetRecycledInstance(packetType, out incPackage))
{
incPackage = (Package)Activator.CreateInstance(packetType);
}https://stackoverflow.com/questions/25115635
复制相似问题