尽管将ReliableFragmented通道分配给网络管理器,但缓冲区错误太大

时间:2017-10-18 17:00:47

标签: c# unity3d networking networkmanager

我在网络上发送大约1.5 MB的图像文件时遇到了问题。我已将NetworkManager配置为使用QoSType ReliableFragmented,但它显然无法正常工作。我究竟做错了什么?附加了NetworkManager组件的代码和屏幕截图。

我接受的错误是:

NetworkWriter WriteBytes: buffer is too large (1699064) bytes. The maximum buffer size is 64K bytes.
UnityEngine.Networking.NetworkWriter:WriteBytesFull(Byte[])
TextureMessage:Serialize(NetworkWriter)
UnityEngine.Networking.NetworkServer:SendToAll(Int16, MessageBase)
Server:SendTexture(Texture2D, String) (at Assets/Scripts/Server.cs:41)
Server:SendOnButtonPress() (at Assets/Scripts/Server.cs:28)
UnityEngine.EventSystems.EventSystem:Update()

启动网络和序列化数据的代码

TextureMessage.cs

using UnityEngine.Networking;

public class TextureMessage : MessageBase
{
    public byte[] textureBytes;
    public string message; //Optional
}

MyMsgType.cs

using UnityEngine.Networking;

public class MyMsgType
{
    public static short texture = MsgType.Highest + 1;
}

Server.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

public class Server : MonoBehaviour {

    public Texture2D textureToSend;
    string messageToSend = "Test Message";

    // Use this for initialization
    void Start ()
    {
        NetworkManager.singleton.StartHost();
        Debug.Log("Server Started.");
    }

    public void SendOnButtonPress()
    {
        SendTexture(textureToSend, messageToSend);
    }

    //Call to send the Texture and a simple string message
    public void SendTexture(Texture2D texture, string message)
    {
        TextureMessage msg = new TextureMessage();

        //Convert Texture2D to byte array

        msg.textureBytes = texture.GetRawTextureData();
        msg.message = message;

        NetworkServer.SendToAll(MyMsgType.texture, msg);
    }
}

Network Manager Component

1 个答案:

答案 0 :(得分:0)

内部如何运作。

NetworkServer.SendToAll():

static public bool SendToAll(short msgType, MessageBase msg)
{
    if (LogFilter.logDev) { Debug.Log("Server.SendToAll msgType:" + msgType); }
    bool result = true;

    // this list holds all connections (local and remote)
    for (int i = 0; i < connections.Count; i++)
    {
        NetworkConnection conn = connections[i];
        if (conn != null)
            result &= conn.Send(msgType, msg);
    }

    return result;
}

NetworkConnection公共构造函数:

public NetworkConnection()
{
    m_Writer = new NetworkWriter();
}

NetworkConnection.Send():

public virtual bool Send(short msgType, MessageBase msg)
{
    return SendByChannel(msgType, msg, Channels.DefaultReliable);
}

NetworkConnection.SendByChannel():

public virtual bool SendByChannel(short msgType, MessageBase msg, int channelId)
{
    m_Writer.StartMessage(msgType);
    msg.Serialize(m_Writer);
    m_Writer.FinishMessage();
    return SendWriter(m_Writer, channelId);
}

如您所见,它使用NetworkWriter序列化您的邮件。 NetworkWriter具有大小为64Kb的缓冲区。您无法序列化大于64K的对象。所以你至少有两个解决方案:

  1. 将纹理分段为小于64K的数组/列表,并逐步连续发送。

  2. 重写所有网络代码。