博主環境(所有文件都在最底下):
- Unity環境: 2018.1.0b11(64bit)
- java環境:jdk 1.8,
- netty環境:netty-all-4.1.16.Final.jar
- protobuf環境:protobuf-java-3.3.0
- python環境:python 2.7
網絡協議:
- 使用簡單的協議一段完整的數據,前4位byte是數據總長度,向後偏移4位是protoId,用於指向解析的protoBytes
JAVA解析數據的地方:
文件:NioServerHandler.java
protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
// TODO Auto-generated method stub
ByteBuf buf=(ByteBuf) msg;
int totalByteLen = buf.readableBytes();
int indeLne = 0;
//解包
while(totalByteLen>indeLne) {
buf.readBytes(dataLenBytes,0,4);
int totalLen = Utils.bytesToInt(dataLenBytes, 0);
indeLne += 4;
buf.readBytes(dataLenBytes,0,4);
int protoId = Utils.bytesToInt(dataLenBytes, 0);
indeLne += 4;
byte[]protoData = new byte[totalLen - 8];
buf.readBytes(protoData,0,totalLen-8);
indeLne += totalLen-8;
Utils.Parse(protoId, protoData);
}
/***
* readBytes這個方法的三個參數分別是:(1)複製目標地址,(2)起始位置注意這裏的起始位置如果寫0,他就是0+你上次讀取的位置,(3)複製數據長度
*
*/
}
//這是Utils裏面的方法
public static void Parse(int protoId,byte[] protoData) {
try {
if(protoId == 1001) {
Person person = Person.parseFrom(protoData);
System.out.println("\n解析成功:\n"+person.toString());
}
}catch (Exception e) {
e.printStackTrace();
}
}
Lua處理解析數據和發送加密protobuffer數據的地方:
--接收數據
function NetWork.Receive(data)
local protoId = data:GetProtoId()
local luaBytes = data:ReadBuffer()
local pbName = UNITY.CMD2PB[protoId].name
local pbData = pb.decode(pbName, luaBytes)
GameNetManager:sendNetMessage(protoId,pbData)
--測試發送
local personData = {
name = "ilse",
age = 18,
contacts = {
{ name = "alice", phonenumber = 12312341234 },
{ name = "bob", phonenumber = 45645674567 }
}
}
NetWork.SendProtoData(1001,personData)
local datac =0
end
--發送數據
function NetWork.SendProtoData(protoId,data)
local pbName = UNITY.CMD2PB[protoId].name
local bytes = assert(pb.encode(pbName, data))
local ByteBuffer = GameByteBuffer.getNewInstance()
ByteBuffer:WriteBuffer(protoId,bytes)
local gameSoketClient = GameSoketClient.GetInstance()
gameSoketClient:WriteGameByteBuffer(ByteBuffer)
end
C#處理數據的地方:
文件:GameSoketClient.cs
void OnReceive(byte[] bytes, int length)
{
// Array.Reverse(bytes, 0, length);
//拆包處理分包,協議是最前面4位是總長度,然後偏移4位是protoid,最後是protoData
int resolveLen = 0;
while (resolveLen<length)
{
//數據段大小
int size = BitConverter.ToInt32(bytes, 0);
resolveLen += 4;
//protoId
int protoId = BitConverter.ToInt32(bytes, resolveLen);
resolveLen += 4;
//
int prptoDataSize = size - 4 - 4;
//數據
GameByteBuffer ByteBuffer = GameByteBuffer.getNewInstance();
ByteBuffer.ParseByteBuffer(ref bytes, resolveLen, prptoDataSize, protoId);
ReceiveBytesQueue.Enqueue(ByteBuffer);
resolveLen += prptoDataSize;
}
}
最後我們來看看運行結果:
你可能需要的源代碼(注意所有的源碼和工具都有說明,請先看下載說明):