黑马程序员技术交流社区
标题:
C#、Unity网络通信中基于字节码的自定义协议解码
[打印本页]
作者:
aisini
时间:
2014-7-28 18:39
标题:
C#、Unity网络通信中基于字节码的自定义协议解码
C#、Unity基于字节的网络通信中字节码解析类,类似java中的ByteBuffer,不过这个实现是参考的netty4中的ByteBuf类。
因为网络通道中是高字节序列,所以本类没有考虑低字节序列
public class ByteBuffer
{
private byte[] buf;
private int readIndex = 0;
private int writeIndex = 0;
private int markReadIndex = 0;
private int markWirteIndex = 0;
private int capacity;
private ByteBuffer(int capacity)
{
buf = new byte[capacity];
this.capacity = capacity;
}
private ByteBuffer(byte[] bytes)
{
buf = bytes;
this.capacity = bytes.Length;
}
public static ByteBuffer Allocate(int capacity)
{
return new ByteBuffer(capacity);
}
public static ByteBuffer Allocate(byte[] bytes)
{
return new ByteBuffer(bytes);
}
public void Write(byte[] bytes)
{
int total = bytes.Length + writeIndex;
int len = buf.Length;
FixSizeAndReset(len, total);
for (int i = writeIndex, j = 0; i < total; i++, j++)
{
buf[i] = bytes[j];
}
writeIndex = total;
}
private int FixLength(int length)
{
int n = 2;
int b = 2;
while( b < length) {
b = 2 << n;
n++;
}
return b;
}
private byte[] flip(byte[] bytes)
{
if (BitConverter.IsLittleEndian)
{
Array.Reverse(bytes);
}
return bytes;
}
private int FixSizeAndReset(int currLen, int futureLen)
{
if (futureLen > currLen)
{
byte[] newbuf = new byte[FixLength(currLen) * 2];
Array.Copy(buf, 0, newbuf, 0, currLen);
buf = newbuf;
capacity = newbuf.Length;
}
return futureLen;
}
public void Write(ByteBuffer buffer)
{
if (buffer == null) return;
if (buffer.ReadableBytes() <= 0) return;
Write(buffer.ToArray());
}
public void WriteShort(short value)
{
Write(flip(BitConverter.GetBytes(value)));
}
public void WriteUshort(ushort value)
{
Write(flip(BitConverter.GetBytes(value)));
}
public void WriteInt(int value)
{
//byte[] array = new byte[4];
//for (int i = 3; i >= 0; i--)
//{
// array[i] = (byte)(value & 0xff);
// value = value >> 8;
//}
//Array.Reverse(array);
//Write(array);
Write(flip(BitConverter.GetBytes(value)));
}
public void WriteUint(uint value)
{
Write(flip(BitConverter.GetBytes(value)));
}
public void WriteLong(long value)
{
Write(flip(BitConverter.GetBytes(value)));
}
public void WriteUlong(ulong value)
{
Write(flip(BitConverter.GetBytes(value)));
}
public void WriteFloat(float value)
{
Write(flip(BitConverter.GetBytes(value)));
}
public void WriteByte(byte value)
{
int afterLen = writeIndex + 1;
int len = buf.Length;
FixSizeAndReset(len, afterLen);
buf[writeIndex] = value;
writeIndex = afterLen;
}
public void WriteDouble(double value)
{
Write(flip(BitConverter.GetBytes(value)));
}
public byte ReadByte()
{
byte b = buf[readIndex];
readIndex++;
return b;
}
public int ReadByteToInt()
{
return ReadByte();
}
private byte[] Read(int len)
{
byte[] bytes = new byte[len];
Array.Copy(buf, readIndex, bytes, 0, len);
if (BitConverter.IsLittleEndian)
{
Array.Reverse(bytes);
}
readIndex += len;
return bytes;
}
public ushort ReadUshort()
{
return BitConverter.ToUInt16(Read(2), 0);
}
public short ReadShort()
{
return BitConverter.ToInt16(Read(2), 0);
}
public uint ReadUint()
{
return BitConverter.ToUInt32(Read(4), 0);
}
public int ReadInt()
{
return BitConverter.ToInt32(Read(4), 0);
}
public ulong ReadUlong()
{
return BitConverter.ToUInt64(Read(8), 0);
}
public long ReadLong()
{
return BitConverter.ToInt64(Read(8), 0);
}
public float ReadFloat()
{
return BitConverter.ToSingle(Read(4), 0);
}
public double ReadDouble()
{
return BitConverter.ToDouble(Read(8), 0);
}
public void ReadBytes(byte[] disbytes, int disstart, int len)
{
int size = disstart + len;
for (int i = disstart; i < size; i++)
{
disbytes[i] = this.ReadByte();
}
}
public void DiscardReadBytes()
{
if(readIndex <= 0) return;
int len = buf.Length - readIndex;
byte[] newbuf = new byte[len];
Array.Copy(buf, readIndex, newbuf, 0, len);
buf = newbuf;
readIndex = 0;
writeIndex -= readIndex;
markReadIndex -= readIndex;
if (markReadIndex < 0)
{
markReadIndex = readIndex;
}
markWirteIndex -= readIndex;
if (markWirteIndex < 0 || markWirteIndex < readIndex || markWirteIndex < markReadIndex)
{
markWirteIndex = writeIndex;
}
}
public void Clear()
{
buf = new byte[buf.Length];
readIndex = 0;
writeIndex = 0;
markReadIndex = 0;
markWirteIndex = 0;
}
public void MarkReaderIndex()
{
markReadIndex = readIndex;
}
public void MarkWriterIndex()
{
markWirteIndex = writeIndex;
}
public void ResetReaderIndex()
{
readIndex = markReadIndex;
}
public void ResetWriterIndex()
{
writeIndex = markWirteIndex;
}
public int ReadableBytes()
{
return writeIndex - readIndex;
}
public byte[] ToArray()
{
byte[] bytes = new byte[writeIndex];
Array.Copy(buf, 0, bytes, 0, bytes.Length);
return bytes;
}
public int GetCapacity()
{
return this.capacity;
}
}
复制代码
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2