kcp源码
里面有IKCP_WND_RCV 常量值
kcp
默认为128 那么可知 这个是包的总数量
count = (len + kcp->mss – 1) / kcp->mss;
kcp->mss = kcp->mtu – IKCP_OVERHEAD;
也就是1400-24=1376
带入式子
128=(x+1376-1)/1376
则x=174753 则当x=174753时候 数据刚好过不去 那么就是174752为最大值
我定义的包头为 4(crc)+8(sNo)+4(totalPage)+4(currentPage)+4(dataSize)=24
则纯数据为174728
发送分包数据结构为 crc+sNo+totalPage+currentPage+dataSize+data
总包数据结构为 messageId+oriDataLength+compressDataLength+data
发送流程
SendMessage(int messageId,byte[] buffer)
{
compressData=Compress(buffer);
stream s =new stream;
s.reset;
s.writeUint32(messageId);
s.writeUint32(buffer.length);
s.writeUint32(compressData.Length);
Splitpackage(messageId,s.tobyte[]);
}
Splitpackage(int messageId,byte[] bytes)
{
stream s=new stream;
int MaxPageSize=x; //这个就是上文的X
int remain=bytes.length%x;
int totalPage=0;
int currentPage=0;
if(remain==0)
{
totalPage=bytes.length/MaxPageSize;
}
else
{
totalPage=bytes.length/MaxPageSize+1;
}
int begain=0;
int copylen=MaxPageSize;
for(int i=0;i<totalPage;i++)
{
currentPage=i+1;
begain=i*MaxPageSize;
if(i==totalPage-1)
{
copylen=bytes.length-begain;
}
else
{
copylen=MaxPageSize;
}
arraySegment<byte> data=new arraySegment<byte>(bytes,begain,copylen).toArray();
s.reset;
kcpNo+=1;
s.writeUint64(kcpNo);
s.writeUint32(totalPage);
s.writeUint32(currentPage);
s.writeUint32(copylen);
s.write(data.array);
uint crc=calcCrc(s.tobyte);
s.writeUint32(crc);
s.writeUint64(kcpNo);
s.writeUint32(totalPage);
s.writeUint32(currentPage);
s.writeUint32(copylen);
s.write(data.array);
send(s.toArray);
}
}
接收流程
void PrePack(byte[] pack)
{
stream s=new stream();
s.write(pack);
uint crc=readUnit32();
ulong kcpNo=readUnit64();
uint totalPage=readUnit32();
uint currentPage=readUnit32();
uint size=readUnit32();
arraySegment<byte> dataBuffer=new arraySegment<byte>(pack,s.position,dataSize);
int size=8+4+4+4+dataSize;
arraySegment<byte> crcBuffer=new arraySegment<byte>(pack,4,size);
if(!crcIsVaild(crcBuffer,crc))
{
crc error;
}
if(totalPage==1)
{
if(currentPage==1)
{
UnpackNew(dataBuffer.toArray);
}
}
else if(totalPage>1)
{
if(currentPage==1)
{
onepackSteam.position=0
}
onepackSteam.write(dataBuffer.toArray);
if(currentPage==totalPage)
{
UnpackNew(onepackSteam.toArray);
}
}
}
void UnpackNew(byte[] buffer)
{
unpackstream.position=0;
unpackstream.write(buffer,0,buffer.length);
unpackstream.position=0;
uint messid=readUnit32(unpackstream);
uint messageLen=readUnit32(unpackstream);
uint messcomLenth=readUnit32(unpackstream);
arraySegment<byte> dataBuffer=new arraySegment<byte>(buffer,unpackstream.position,messcomLenth);
if(messageLen!=messcomLenth)
{
byte[] uncompressData=Decompress(dataBuffer.toArray,messageLen);
dataBuffer=uncompressData;
}
OnRecive(messageId,dataBuffer.toArray)
}
- 本文固定链接: https://bonostallone.com/?p=127
- 转载请注明: bono 于 bonoStallone 明天的烟火 发表