你好,当我尝试将序列化对象发送到服务器时,我有"内存不可扩展"问题,我不明白为什么,我的缓冲区的大小为1024字节,但我只发送一个对象总共24个字节。序列化增加对象的大小??
我不知道,所以除了查看与我的问题有关的论坛主题外,我没有尝试过任何特别的事情。
private const int BYTE_SIZE = 1024;
发送功能:
public void sendToServer(NMSG msg, int channelId)
{
if (!PacketHandler.packets.Contains(msg.GetType()))
{
Debug.Log("packet not registered");
return;
}
byte error;
byte[] buffer = new byte[BYTE_SIZE];
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream ms = new MemoryStream(buffer);
formatter.Serialize(ms, msg); //error occur here.
int bufferSize = BYTE_SIZE;
NetworkTransport.Send(hostId, connectionId, channelId, buffer, bufferSize, out error);
}
发送对象:
using UnityEngine;
[System.Serializable]
public class NMSG_CreatePlayer : NMSG
{
public string playerName;
public float? posX;
public float? posY;
public int? shipSlot;
public int? skinSlot;
public int? particleSlot;
public int? trailSlot1;
public int? trailSlot2;
public int? connectionId;
public NMSG_CreatePlayer(string playerName) : base((byte)PacketHandler.packets.IndexOf(typeof(NMSG_CreatePlayer)))
{
this.playerName = playerName;
}
public NMSG_CreatePlayer(string playerName, int connectionId, float posX, float posY, int shipSlot, int skinSlot, int particleSlot, int trailSlot1, int trailSlot2) : base((byte)PacketHandler.packets.IndexOf(typeof(NMSG_CreatePlayer)))
{
this.playerName = playerName;
this.posX = posX;
this.posY = posY;
this.shipSlot = shipSlot;
this.skinSlot = skinSlot;
this.particleSlot = particleSlot;
this.trailSlot1 = trailSlot1;
this.trailSlot2 = trailSlot2;
this.connectionId = connectionId;
}
//Here packet data send from server
public override void HandleClient(NMSG msg)
{
NMSG_CreatePlayer cmsg = (NMSG_CreatePlayer)msg;
Player p = new Player(cmsg.playerName,0);
Ship ship = (Ship)Item.getItemById((int)cmsg.shipSlot);
Skin skin = (Skin)Item.getItemById((int)cmsg.skinSlot);
Particle particle = (Particle)Item.getItemById((int) this.particleSlot);
Trail trail1 = (Trail)Item.getItemById((int) this.trailSlot1);
Trail trail2 = (Trail)Item.getItemById((int) this.trailSlot2);
GameObject instance = GameObject.Instantiate(trail2 != null ? Main.instance.modelInitializator.playerModel_2Trail : Main.instance.modelInitializator.playerModel_1Trail, GameObject.Find("World").transform);
p.setPosition((float)cmsg.posX, (float)cmsg.posY);
instance.transform.localPosition = new Vector3(p.getPositionX(),p.getPositionY(), 0);
instance.name = playerName;
p.setObject(instance);
p.applyEquipment(ship, skin, particle, trail1, trail2);
p.setName(playerName);
p.setConnectionId((int)connectionId);
instance.transform.localEulerAngles = new Vector3(0, 0, 0);
Client.getClient().players.Add((int)connectionId, p);
if ((int) connectionId == Client.getClient().getConnectionId())
{
instance.AddComponent<PlayerController>();
Main.player = p;
Client.getClient().gm = GameManager.createGameManager(p);
p.isInGame = true;
}
}
//Here packet data send from client
public override void HandleServer(NMSG msg, int connectionId)
{
NMSG_CreatePlayer cmsg = (NMSG_CreatePlayer)msg;
Player p = Server.getPlayer(connectionId);
p.setName(cmsg.playerName);
float posx = World.generateRandomPosX();
float posy = World.generateRandomPosY();
p.setPosition(posx, posy);
GameObject instance = GameObject.Instantiate(Main.instance.modelInitializator.player, GameObject.Find("World").transform);
instance.transform.localPosition = new Vector3(posx, posy, 0);
p.playerGameObject = instance;
int shipSlot = p.pData.shipSlot == null ? 0 : p.pData.shipSlot.getItemId();
int skinSlot = p.pData.skinSlot == null ? 0 : p.pData.skinSlot.getItemId();
int particleSlot = p.pData.particleSlot == null ? 0 : p.pData.particleSlot.getItemId();
int trailSlot1 = p.pData.trailSlot1 == null ? 0 : p.pData.trailSlot1.getItemId();
int trailSlot2 = p.pData.trailSlot2 == null ? 0 : p.pData.trailSlot2.getItemId();
Server.getServer().sendToAll(new NMSG_CreatePlayer(p.getName(), p.getConnectionId(), p.getPositionX(), p.getPositionY(), shipSlot, skinSlot, particleSlot, trailSlot1, trailSlot2),Server.getServer().reliableChannel);
p.isInGame = true;
}
}
}
NMSG类:
[System.Serializable]
public abstract class NMSG
{
private byte? discriminator = null;
public NMSG(byte discriminator) { this.discriminator = discriminator; }
public byte? getPacketId()
{
return this.discriminator;
}
public abstract void HandleServer(NMSG msg, int connectionId);
public abstract void HandleClient(NMSG msg);
}
我完全迷失了...我不耐烦地等待着您的帮助。
该类型至少需要1165个字节来二进制序列化器。因此,您需要使Byte_size更大,或者让MemoryStream自动增长。
这是一个repro:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp25
{
[System.Serializable]
public class NMSG_CreatePlayer : NMSG
{
public NMSG_CreatePlayer() : base(0)
{ }
public string playerName;
public float? posX;
public float? posY;
public int? shipSlot;
public int? skinSlot;
public int? particleSlot;
public int? trailSlot1;
public int? trailSlot2;
public int? connectionId;
}
[System.Serializable]
public abstract class NMSG
{
private byte? discriminator = null;
public NMSG(byte discriminator) { this.discriminator = discriminator; }
}
class Program
{
public static void sendToServer(NMSG msg, int channelId)
{
int BYTE_SIZE = 1024;
byte[] buffer = new byte[BYTE_SIZE];
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream ms = new MemoryStream(buffer);
formatter.Serialize(ms, msg);
Console.WriteLine(ms.Position);
}
static void Main(string[] args)
{
var o = new NMSG_CreatePlayer();
sendToServer(o, 0);
Console.ReadKey();
}
}
}