我需要一些真正的帮助。我不确定如何解决CRC不匹配错误。我要做的就是将字节数组从我的客户端发送到我的服务器,但出现此错误:
UNet 客户端断开连接错误:CRCMismatch UnityEngine.Networking.NetworkIdentity:UNetStaticUpdate()
一个多月来,我一直在尝试将这些点连接起来,让网络正确运行,但我每向前迈出一步,都会导致后退五步。我基本上一直在兜圈子,我已经完成了所有存在的 Unity 网络教程,但我仍然很迷茫。我真的需要帮助解决这个问题。有人可以帮我解决这个问题吗?我还在下面附加了完整的代码。提前谢谢你!
客户端
public class Client : NetworkBehaviour {
NetworkClient client = new NetworkClient();
private const int MAX_CONNECTION = 100;
private string serverIP = "127.0.0.1";
private int port = 5708;
private int hostId;
private int webHostId;
private int reliableChannel;
private int reliableSeqChannel;
private int reliableFragChannel;
private int unreliableChannel;
private int unreliableSeqChannel;
private string playerName;
private int connectionId;
private float connectionTime;
private bool isStarted = false;
private bool isConnected = false;
private bool readyToSendMsg = false;
private byte error;
private GameObject infoDisplayText;
public Texture2D texToSend;
string typeToSend = "Deer";
string idToSend = "1";
int strengthToSend = 80;
int hitPointsToSend = 2;
private string GetPlayerName()
{
switch (Network.player.ipAddress.ToString())
{
case "192.168.1.160":
playerName = "SMO Server";
break;
case "192.168.1.161":
playerName = "SMO Client 1";
break;
case "192.168.1.162":
playerName = "SMO Client 2";
break;
case "192.168.1.163":
playerName = "SMO Client 3";
break;
case "192.168.1.164":
playerName = "SMO Client 4";
break;
default:
playerName = "SMO UNREG";
break;
}
return playerName;
}
private void Start()
{
infoDisplayText = GameObject.Find("InfoDisplay");
client.RegisterHandler(AnimalDataMsgType.SYSTEM_CONNECT, OnConnected);
client.RegisterHandler(AnimalDataMsgType.SYSTEM_DISCONNECT, OnDisconnected);
client.RegisterHandler(AnimalDataMsgType.SYSTEM_ERROR, OnError);
client.Connect(serverIP, port);
}
public void Connect()
{
string pName = GetPlayerName();
if (pName == "")
return;
playerName = pName;
NetworkTransport.Init();
ConnectionConfig cc = new ConnectionConfig();
reliableChannel = cc.AddChannel(QosType.Reliable);
reliableSeqChannel = cc.AddChannel(QosType.ReliableSequenced);
reliableFragChannel = cc.AddChannel(QosType.ReliableFragmented);
unreliableChannel = cc.AddChannel(QosType.Unreliable);
unreliableSeqChannel = cc.AddChannel(QosType.UnreliableSequenced);
cc.PacketSize = 1440;
cc.FragmentSize = 900;
cc.ResendTimeout = 1000;
cc.DisconnectTimeout = 5000;
cc.ConnectTimeout = 1000;
cc.MaxConnectionAttempt = 5;
HostTopology topo = new HostTopology(cc, MAX_CONNECTION);
hostId = NetworkTransport.AddHost(topo, 0);
// Run client/server on different machines
//hostID = NetworkTransport.AddHost(topo, port, null);
connectionId = NetworkTransport.Connect(hostId, serverIP, port, 0, out error);
infoDisplayText = GameObject.Find("InfoDisplay");
infoDisplayText.GetComponent<Text>().text += playerName + " connected.n";
connectionTime = Time.time;
isConnected = true;
}
private void Update()
{
if (!isConnected)
return;
int recHostId, connectionId, channelId;
byte[] recBuffer = new byte[1024];
int bufferSize = 1024;
int dataSize;
byte error;
NetworkEventType recData = NetworkTransport.Receive(out recHostId, out connectionId, out channelId, recBuffer, bufferSize, out dataSize, out error);
switch (recData)
{
case NetworkEventType.ConnectEvent:
Debug.Log("Player " + connectionId + " has connected");
infoDisplayText.GetComponent<Text>().text += "Connected to Server.n";
break;
}
}
public void SendOnButtonPress()
{
if (readyToSendMsg == true)
SendTexture(texToSend, typeToSend, idToSend, strengthToSend, hitPointsToSend);
}
//Call to send the Texture and a simple string message
public void SendTexture(Texture2D tex, string type, string id, int strength, int hitpoints)
{
AnimalData animalData = new AnimalData();
animalData.Tex = tex.GetRawTextureData();
animalData.Type = type;
animalData.Id = id;
animalData.Strength = strength;
animalData.Hitpoints = hitpoints;
client.Send(AnimalDataMsgType.animalData, animalData);
}
private void OnConnected(NetworkMessage netMsg)
{
readyToSendMsg = true;
Debug.Log("Connected to server");
}
private void OnDisconnected(NetworkMessage netMsg)
{
readyToSendMsg = false;
Debug.Log("Disconnected from server");
}
private void OnError(NetworkMessage netMsg)
{
//SystemErrorMessage errorMsg = reader.SmartRead<SystemErrorMessage>();
// Debug.Log("Error connecting with code " + errorMsg.errorCode);
Debug.Log("Error connecting.");
}
服务器端
public class Server : NetworkBehaviour
{
private const int MAX_CONNECTION = 100;
private int port = 5708;
private int hostId;
private int webHostId;
private int reliableChannel;
private int reliableSeqChannel;
private int reliableFragChannel;
private int unreliableChannel;
private int unreliableSeqChannel;
private bool isStarted = false;
private byte error;
private GameObject infoDisplayText;
private void Awake()
{
infoDisplayText = GameObject.Find("InfoDisplay");
}
private void Start()
{
NetworkTransport.Init();
ConnectionConfig cc = new ConnectionConfig();
reliableChannel = cc.AddChannel(QosType.Reliable);
reliableSeqChannel = cc.AddChannel(QosType.ReliableSequenced);
reliableFragChannel = cc.AddChannel(QosType.ReliableFragmented);
unreliableChannel = cc.AddChannel(QosType.Unreliable);
unreliableSeqChannel = cc.AddChannel(QosType.UnreliableSequenced);
HostTopology topo = new HostTopology(cc, MAX_CONNECTION);
hostId = NetworkTransport.AddHost(topo, port, null);
if (NetworkTransport.IsStarted)
{
isStarted = true;
Debug.Log("NetworkTransport is Started.");
infoDisplayText.GetComponent<Text>().text += "NetworkTransport is Started.n";
}
Debug.Log("Server Started.");
infoDisplayText.GetComponent<Text>().text += "Server Started.n";
setupRegisterHandler();
}
private void Update()
{
if (!isStarted)
return;
int recHostId, connectionId, channelId;
byte[] recBuffer = new byte[1024];
int bufferSize = 1024;
int dataSize;
byte error;
NetworkEventType recData = NetworkTransport.Receive(out recHostId, out connectionId, out channelId, recBuffer, bufferSize, out dataSize, out error);
switch (recData)
{
case NetworkEventType.ConnectEvent:
Debug.Log("Player " + connectionId + " has connected");
infoDisplayText.GetComponent<Text>().text += "Player " + connectionId + " has connectedn";
break;
}
}
// Create a client and connect to the server port
public void setupRegisterHandler()
{
NetworkServer.Listen(port);
Debug.Log("Registering server callbacks");
NetworkServer.RegisterHandler(AnimalDataMsgType.animalData, OnTextureReceive);
}
//Called when texture is received
public void OnTextureReceive(NetworkMessage netMsg)
{
AnimalData animalData = netMsg.ReadMessage<AnimalData>();
string type = animalData.Type;
Debug.Log("Type : " + type);
string id = animalData.Id;
Debug.Log("ID : " + id);
int strength = animalData.Strength;
Debug.Log("Strength : " + strength);
int hitpoints = animalData.Hitpoints;
Debug.Log("Hit Points : " + hitpoints);
//Your Received Texture2D
Texture2D receivedtexture = new Texture2D(1280, 1024);
receivedtexture.LoadRawTextureData(animalData.Tex);
receivedtexture.Apply();
Debug.Log(type + " data received!");
infoDisplayText.GetComponent<Text>().text += type + " data received!n";
}
}
动物数据Msg类型类
public class AnimalDataMsgType
{
public static short animalData = MsgType.Highest + 1;
public static short SYSTEM_CONNECT = MsgType.Connect;
public static short SYSTEM_DISCONNECT = MsgType.Disconnect;
public static short SYSTEM_ERROR = MsgType.Error;
}
动物数据类
public class AnimalData : MessageBase
{
public byte[] Tex; // data coming from CanvasController
public string Type; // data coming from CanvasController
public string Id; // data coming from GameManager
public int Strength; // data coming from PlayerController
public int Hitpoints; // data coming from PlayerController
public bool IsAlive; // data coming from PlayerController
}
我通过在client.Connect(serverIP, port);
之前添加client.Configure(cc, 1);
来解决我的问题。问题是我的网络客户端连接配置文件需要设置为我的网络传输主机拓扑中定义的相同配置设置,而不为我的客户端设置连接配置。连接功能导致CRC不匹配。此外,在创建 NetworkClient 实例后发送消息时,我使用 client.SendByChannel
以便我可以设置我的 channelId。
部分或全部 ConnectionConfig 值必须在主机上和客户端上匹配。当我指定不同的断开连接超时值时遇到相同的问题。