public void OnReceived(byte[] rbuf, int offset, int count) { int currentRecvLen = count; recvStream.Write(rbuf, offset, currentRecvLen); recvLen += currentRecvLen; Contract.Assert(recvLen == recvStream.Position); int initialRecvLen = recvLen; int readOffset = 0; int loopCount = 0; // rewind to read recvStream.Position = 0; while (recvLen >= msgLengthFieldLen) { uint msgLen = 0; MsgSerializer.ReadUInt32(recvStream, out msgLen); if (msgLen == 0) { throw new InvalidOperationException( $"MsgLength zero! BufferLen:{recvStream.Length}, " + $"CurrentRecvLen:{currentRecvLen}, RecvLen:{currentRecvLen}, " + $"LoopCount:{loopCount}" ); } if (recvLen < msgLen) { break; } uint msgType = 0; MsgSerializer.ReadUInt32(recvStream, out msgType); var serializer = MsgSerializerFactory.Instance().Get(msgType); if (serializer == null) { } else { try { var m = (Msg)serializer.Unpack(recvStream); m.Protocol = this; listener.Notify(m); ++messageCount; } catch (Exception e) { throw e; } } readOffset += (int)msgLen; recvLen -= (int)msgLen; } if (readOffset > 0) { // 버퍼를 앞으로 옮김. MemoryStream의 GetBuffer()는 내부 버퍼를 돌려줌. var buf = recvStream.GetBuffer(); int tailLen = initialRecvLen - (int)readOffset; if (tailLen > 0) { Buffer.BlockCopy(buf, readOffset, buf, 0, tailLen); } } recvStream.Position = recvLen; // 현재 받은 위치 끝으로 누적하기위해 이동 }
public void Set(uint msgType, Type type) { serializers[msgType] = new MsgSerializer(type, msgType); }