大家好,我切换到了Json序列化,这次序列化工作很完美,问题来自于反序列化,我有一个异常……
错误:
XmlException: Encountered an unexpected character '
System.Xml.XmlExceptionHelper.ThrowXmlException (System.Xml.XmlDictionaryReader reader, System.Xml.XmlException exception) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.XmlJsonReader.Read () (at <3abed3971fab48b2a085712365cc627f>:0)
System.Xml.XmlBaseReader.ReadEndElement () (at <3abed3971fab48b2a085712365cc627f>:0)
System.Xml.XmlBaseReader.ReadElementContentAsString () (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.XmlReaderDelegator.ReadElementContentAsString () (at <3abed3971fab48b2a085712365cc627f>:0)
System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at <1f0c1ef1ad524c38bbc5536809c46b48>:0)
Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.
System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at <1f0c1ef1ad524c38bbc5536809c46b48>:0)
System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) (at <1f0c1ef1ad524c38bbc5536809c46b48>:0)
System.Runtime.Serialization.Json.JsonFormatReaderInterpreter.ReadValue (System.Type type, System.String name) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.JsonFormatReaderInterpreter.ReadMembers (System.Int32 index, System.Runtime.Serialization.ClassDataContract classContract, System.Runtime.Serialization.BitFlagsGenerator expectedElements, System.Int32& memberIndex) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.JsonFormatReaderInterpreter.ReadMembers (System.Runtime.Serialization.ClassDataContract classContract, System.Runtime.Serialization.ExtensionDataObject extensionData) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.JsonFormatReaderInterpreter.ReadClass (System.Runtime.Serialization.ClassDataContract classContract) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.JsonFormatReaderInterpreter.ReadFromJson (System.Runtime.Serialization.XmlReaderDelegator xmlReader, System.Runtime.Serialization.Json.XmlObjectSerializerReadContextComplexJson context, System.Xml.XmlDictionaryString emptyDictionaryString, System.Xml.XmlDictionaryString[] memberNames) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.JsonFormatReaderGenerator+CriticalHelper+<>c__DisplayClass0_0.<GenerateClassReader>b__0 (System.Runtime.Serialization.XmlReaderDelegator xr, System.Runtime.Serialization.Json.XmlObjectSerializerReadContextComplexJson ctx, System.Xml.XmlDictionaryString emptyDictionaryString, System.Xml.XmlDictionaryString[] memberNames) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.JsonClassDataContract.ReadJsonValueCore (System.Runtime.Serialization.XmlReaderDelegator jsonReader, System.Runtime.Serialization.Json.XmlObjectSerializerReadContextComplexJson context) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.JsonDataContract.ReadJsonValue (System.Runtime.Serialization.XmlReaderDelegator jsonReader, System.Runtime.Serialization.Json.XmlObjectSerializerReadContextComplexJson context) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.DataContractJsonSerializer.ReadJsonValue (System.Runtime.Serialization.DataContract contract, System.Runtime.Serialization.XmlReaderDelegator reader, System.Runtime.Serialization.Json.XmlObjectSerializerReadContextComplexJson context) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.XmlObjectSerializerReadContextComplexJson.ReadDataContractValue (System.Runtime.Serialization.DataContract dataContract, System.Runtime.Serialization.XmlReaderDelegator reader) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize (System.Runtime.Serialization.XmlReaderDelegator reader, System.String name, System.String ns, System.Type declaredType, System.Runtime.Serialization.DataContract& dataContract) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize (System.Runtime.Serialization.XmlReaderDelegator xmlReader, System.Type declaredType, System.Runtime.Serialization.DataContract dataContract, System.String name, System.String ns) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.XmlObjectSerializerReadContextComplex.InternalDeserialize (System.Runtime.Serialization.XmlReaderDelegator xmlReader, System.Type declaredType, System.Runtime.Serialization.DataContract dataContract, System.String name, System.String ns) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.DataContractJsonSerializer.InternalReadObject (System.Runtime.Serialization.XmlReaderDelegator xmlReader, System.Boolean verifyObjectName) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.XmlObjectSerializer.InternalReadObject (System.Runtime.Serialization.XmlReaderDelegator reader, System.Boolean verifyObjectName, System.Runtime.Serialization.DataContractResolver dataContractResolver) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions (System.Runtime.Serialization.XmlReaderDelegator reader, System.Boolean verifyObjectName, System.Runtime.Serialization.DataContractResolver dataContractResolver) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions (System.Runtime.Serialization.XmlReaderDelegator reader, System.Boolean verifyObjectName) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.DataContractJsonSerializer.ReadObject (System.Xml.XmlDictionaryReader reader) (at <3abed3971fab48b2a085712365cc627f>:0)
System.Runtime.Serialization.Json.DataContractJsonSerializer.ReadObject (System.IO.Stream stream) (at <3abed3971fab48b2a085712365cc627f>:0)
Server.Update () (at Assets/Scripts/Network/Server.cs:116)代码:
来自客户端类的发送函数:
public void sendToServer(NMSG msg, int channelId)
{
    if (!PacketHandler.packets.Contains(msg.GetType()))
    {
        Debug.Log("packet not registered");
        return;
    }
    byte error;
    byte[] buffer;
    var stream = new MemoryStream();
    var serializer = new DataContractJsonSerializer(typeof(NMSG));
    serializer.WriteObject(stream, msg);
    buffer = stream.ToArray();
    int bufferSize = buffer.Length;
    NetworkTransport.Send(hostId, connectionId, channelId, buffer, bufferSize, out error);
}反序列化的代码:
MemoryStream memoryStream = new MemoryStream(recBuffer);
memoryStream.Position = 0;
var ser = new DataContractJsonSerializer(typeof(NMSG));
NMSG msg = (NMSG)ser.ReadObject(memoryStream);
onData(connectionId, channelId, recHostId, msg);NMSG类:
using System;
using System.Runtime.Serialization;
[DataContract]
[KnownType("GetKnownTypes")]
public abstract class NMSG
{
    [DataMember]
    private byte? discriminator = null;
    public NMSG()
    {
    }
    public NMSG(byte discriminator)
    {
        this.discriminator = discriminator;
    }
    public byte? getPacketId()
    {
        return this.discriminator;
    }
    public static Type[] GetKnownTypes()
    {
        return PacketHandler.packets.ToArray();
    }
    public abstract void HandleServer(NMSG msg, int connectionId);
    public abstract void HandleClient(NMSG msg);
}我发送到服务器的
[DataContract]
public class NMSG_ConnectAccount : NMSG
{
    [DataMember]
    public string username;
    [DataMember]
    public string password;
    public NMSG_ConnectAccount()
    {
    }
    public NMSG_ConnectAccount(string username, string password) : base((byte)PacketHandler.packets.IndexOf(typeof(NMSG_ConnectAccount)))
    {
        this.username = username;
        this.password = password;
    }
    public override void HandleClient(NMSG msg) 
    {
    }
    public override void HandleServer(NMSG msg, int connectionId)
    {
        NMSG_ConnectAccount cmsg = (NMSG_ConnectAccount)msg;
        Server server = Server.getServer();
        Mysql mysql = server.mysql;
        password = EncryptionUtils.MD5Hash(password);
        mysql.openMysqlConnection();
        MySqlCommand commandsql = new MySqlCommand("SELECT * FROM users WHERE username = '" + cmsg.username + "'", mysql.con);
        MySqlDataReader MyReader = commandsql.ExecuteReader();
        string activated = "";
        string mpassword = "";
        string muser = "";
        if (MyReader.Read())
        {
            activated = MyReader["confirmed"].ToString();
            mpassword = MyReader["password"].ToString();
            muser = MyReader["username"].ToString();
        }
        MyReader.Close();
        if (mpassword != cmsg.password || cmsg.username != muser)
        {
            server.sendToPlayer(new NMSG_ConnectionMessage(cmsg.username,false,false), server.reliableChannel, connectionId);
            return;
        }
        if (server.users.ContainsKey(connectionId))
            server.users[connectionId].setName(muser);
        else
            return;
        if (activated == "False")
        {
            server.sendToPlayer(new NMSG_ConnectionMessage(cmsg.username,false,true), server.reliableChannel, connectionId);
            return;
        }
        server.users[connectionId].pData = new PlayerData(cmsg.username);
        server.users[connectionId].isAuth = true;
        server.sendToPlayer(new NMSG_ConnectionMessage(cmsg.username,true,false), server.reliableChannel, connectionId);
    }
}预先感谢您的帮助
发布于 2019-08-08 20:39:50
这就是我要做的:
packetHandler类:
public class PacketHandler
{
    public static List<System.Type> packets = new List<System.Type>();
    public PacketHandler()
    {
        registerPacket(typeof(NMSG_CreatePlayer));
        registerPacket(typeof(NMSG_UpdatePlayer));
        registerPacket(typeof(NMSG_UpdatePlayerState));
        registerPacket(typeof(NMSG_CreateAccount));
        registerPacket(typeof(NMSG_RegisterMessage));
        registerPacket(typeof(NMSG_ConnectAccount));
        registerPacket(typeof(NMSG_ConnectionMessage));
        registerPacket(typeof(NMSG_ActivateAccountProcess));
        registerPacket(typeof(NMSG_DisconnectAccount));
        registerPacket(typeof(NMSG_PlayerDataTransmission));
        registerPacket(typeof(NMSG_UpdateAccountData));
        registerPacket(typeof(NMSG_UpdateInventory));
        registerPacket(typeof(NMSG_UpdateItemInventory));
        registerPacket(typeof(NMSG_RefreshShop));
        registerPacket(typeof(NMSG_BuyRequest));
    }
    public bool registerPacket(System.Type packet)
    {
        if(!packet.GetType().IsInstanceOfType(typeof(NMSG)))
        {
            throw new System.Exception("Type of packet must be NMSG");
        }
        if(packets.Count >= 256)
        {
            throw new System.Exception("Packets count exceed limit of 255");
        }
        if(packets.Contains(packet))
        {
            throw new System.Exception("Packet already registered");
        }
        packets.Add(packet);
        return true;
    }
}服务器类
private void Start()
    {
        INSTANCE = this;
        NetworkSide.side = NetworkSide.Side.SERVER;
        mysql = new Mysql();
        if (!mysql.openMysqlConnection())
        {
            Debug.Log("ERROR- Server data center not active server closed...");
            return;
        }
        serverProperties = new ServerProperties();
        NetworkTransport.Init();
        ConnectionConfig cc = new ConnectionConfig();
        reliableChannel = cc.AddChannel(QosType.Reliable);
        unreliableChannel = cc.AddChannel(QosType.Unreliable);
        HostTopology topo = new HostTopology(cc, serverProperties.MAX_CONNECTION);
        hostId = NetworkTransport.AddHost(topo, serverProperties.port, null);
        packetHandler = new PacketHandler();
        registerCommand(new CommandHelp("help", "display all commands", null));
        registerCommand(new CommandGive("give", "give item to specified player", new string[] { "<Username>", "<ItemId>" }));
        registerCommand(new CommandStop("stop", "stop server", null));
        EventManager.registerEvent(new DeathEvent());
        EventManager.registerEvent(new AreaQuitEvent());
        EventManager.registerEvent(new AreaEnterEvent());
        EventManager.registerEvent(new DamageEvent());
        ItemInitializer.loadItems();
        world = new World();
        world.Load();
        Debug.Log("Server started in port : " + serverProperties.port);
        Debug.Log("Max Slot = " + serverProperties.MAX_CONNECTION);
        Debug.Log("You can configurate server data in serverProperties.properties");
        isStarted = true;
    }如您所见,所有NMSG类都在start函数中进行了大量注册
客户端:
    void Start()
    {
        client = this;
        packetHandler = new PacketHandler();
        NetworkSide.side = NetworkSide.Side.CLIENT;
        EventManager.registerEvent(new AreaQuitEvent());
        EventManager.registerEvent(new AreaEnterEvent());
        ConnectToServer("127.0.0.1",port);
    }客户端也是如此
现在,我将调试"packets“列表以查看其中包含的内容
服务器控制台:
packets count (Server) 15
NMSG_CreatePlayer
NMSG_UpdatePlayer
NMSG_UpdatePlayerState
NMSG_CreateAccount
NMSG_RegisterMessage
NMSG_ConnectAccount
NMSG_ConnectionMessage
NMSG_ActivateAccountProcess
NMSG_DisconnectAccount
NMSG_PlayerDataTransmission
NMSG_UpdateAccountData
NMSG_UpdateInventory
NMSG_UpdateItemInventory
NMSG_RefreshShop
NMSG_BuyRequest
UnityEngine.Debug:Log(Object)
Server:Start() (at Assets/Scripts/Network/Server.cs:90)客户端控制台:
packets count (Client) 15
NMSG_CreatePlayer
NMSG_UpdatePlayer
NMSG_UpdatePlayerState
NMSG_CreateAccount
NMSG_RegisterMessage
NMSG_ConnectAccount
NMSG_ConnectionMessage
NMSG_ActivateAccountProcess
NMSG_DisconnectAccount
NMSG_PlayerDataTransmission
NMSG_UpdateAccountData
NMSG_UpdateInventory
NMSG_UpdateItemInventory
NMSG_RefreshShop
NMSG_BuyRequest
UnityEngine.Debug:Log(Object)
Client:Start() (at Assets/Scripts/Network/Client.cs:64)所以数据包列表不可能是空的,我不明白为什么它不能工作…
发布于 2019-08-11 01:56:23
问题解决我现在使用手动序列化,它更快,使用更少的空间,我向任何使用序列化发送网络对象的人推荐这种方法。
https://stackoverflow.com/questions/57379981
复制相似问题