前言:Unity3D笔记是我平时做一些好玩的测试和研究,记录的笔记。会比较详细也可能随口一提就过了。 所以大家见谅了,内容一般都会是原创的(非原创我会注明转载)。由于很多内容其他的朋友也肯定研究发表过,大家请指出错误。
之前做的答题游戏,在向服务器申请题目列表时遇到点问题:由于题目过长,所有传过来的json格式的数据自动分包了;需要自己处理下;
我打印了下收到数据:
这边可以明显看到:本来时一条的数据这里被分成两次收到了;于是呢,就没有办法直接解析数据了;
一.粘包和分包现象
该现象主要发生在TCP协议中:由于TCP本身的机制,客户端和服务器会维持一个连接发送数据。如果发送的数据很小,那么会自动把一些小的数据合并在一起发送出去;但是接收端就没办法自己分开了。这就是粘包现象;而当一次发送的数据又过长的时候,TCP就会把该数据分成几部分发送出去,每次接收方就只会接受部分的数据;这就是分包现象;
粘包现象:
客户端发送:hello;
客户端发送:aaaaa;
服务器收到:helloaaaaa;
分包现象:
客户端发送:helloxiaoming;
服务器收到:hell
服务器收到:oxiaoming
就像我遇到的问题一样:服务器发送过来的数据太长了:导致本地的而客户端分两次收到了信息;
二.最简单的处理方式
最简单的方式就是在每次发送数据的时候,在数据的末尾加一个标识符:该标识符不能是数据中出现的符号,不能是常用的符号;我用的是(\n)
直接上代码:
发送的处理:
void loadQuestionAndSend()
{
List<Question> questionList = QuestionLoader.Instance.GetListQuestion();
string questionJson = JsonAndIOHelper.SerializeObject(questionList);
GameData gameData = new GameData(JsonDataType.questionRoom, questionJson);
string gameDataJson = JsonAndIOHelper.SerializeObject(gameData);
SendDataToPlayer(gameDataJson + "\n");
}
前面是序列化的一些步骤,然后在最后添加了“\n”换行符;
接受端:
先定义个缓存的空间:
//用于存放分包遗留的数据
private string buffStr="";
收到数据后处理:
//处理收到的数据
string str = System.Text.Encoding.UTF8.GetString(readBuff,0,count);
Debug.Log(str);
//把上次剩下的数据放入
str = buffStr + str;
//更具换行符,解析
string[] line = str.Split('\n');
for (int i = 0; i < line.Length; i++)
{
//最后一个放入新的缓存
if (i == line.Length - 1)
{
buffStr = line[i];
}
else
{
Debug.Log(line[i]);
NetworkDataHandler.Instance.NetworkDataUpdate(line[i]);
}
说明: 这边呢做的事这么几部:1.每次收到数据后,把前一次遗留的缓存数据加上去;2.根据换行符,隔断数据,得到数据的数组;3.前几个数据都是完整的,最后一个放入缓冲中;
嗯,基本就是这些了;
最后打印下,处理后的数据:可以看到这是完整的json数据了;