private void addEvent(WorldPack Packet) { lock (_events) { bool missEvent = false; for (int i = 0; i < _missedEvents.Count; i++) { if (_missedEvents[i] == Packet.opcode()) { _missedEvents.RemoveAt(i); Debug.LogWarning("ignore missed event: " + Packet.opcode() + ", missed events count: " + _missedEvents.Count); missEvent = true; break; } } if (!missEvent) { _events.Add(Packet); } } }
public void OutPacket(WorldPack pack) { if (!connected()) { return; } UInt16 size = (UInt16)(pack.size() + C2S_PACK_HEAD_SIZE); ByteBuffer data = new ByteBuffer(size); data.W((UInt16)(pack.size() + 4)); data.W((UInt32)pack.opcode()); data.W(pack); _tcpClient.Client.Send(data.contents()); }
//event 3, do receive stuff for clients. // use tcpClients snync reading methods, read them into circular buffer, and make worldpack. // Callback function when receive byte data,Using tcpClient start read sync fucntion. private void _onRead(IAsyncResult result) { Debug.Log("_onRead " + result.ToString()); // check if we have been gc or closed. if (!connected() || null == _netStream) { return; } int readByteThisTime = _netStream.EndRead(result); if (readByteThisTime <= 0) { Debug.LogError("NetErrorCode.NET_RECV_ERROR"); Console.WriteLine("NetErrorCode.NET_RECV_ERROR"); Disconnect(); // TryToConnect(); return; } Debug.Log("_onRead Receive beytes " + readByteThisTime.ToString()); //Console.WriteLine("Receive beytes {0}",readByteThisTime); _wpos += (UInt16)readByteThisTime; // _wpos 为当前系统向_read中数据写到的长度。指向_read中数据的结尾处。 // _rpos指向当前读数据开始的位置,只有在成功读出一个包的时候才改变它。 // 缓存中当前处理实际数据大小为 _wpos-_rpos. // 循环处理多个包之后,缓存中的数据不足以一个包的时候,做自拷贝动作。 // :将 _rpos --> _wpos的数据拷贝到_read开头。 // _wpos and _rpos all --rpos; while (true) { Debug.Log("_onRead(While)" + _wpos.ToString() + " " + _rpos.ToString()); Debug.Log("_onRead(While) _read=" + _read.ToString()); for (int i = 0; i < 11; i++) { Debug.Log("_onRead(While) _read:" + i.ToString() + "->" + _read[i].ToString()); } int size = _wpos - _rpos; System.Diagnostics.Debug.Assert(size >= 0); if (size < 6) { break; /* no head in the apcket, let's wait.*/ } // head: size(u16)+code(u32) UInt16 packetSize = BitConverter.ToUInt16(_read, (int)_rpos); if (packetSize < 4) { Debug.LogError("packetSize<4!!"); break; } packetSize = (UInt16)(packetSize - 4); if (size < packetSize + S2C_PACK_HEAD_SIZE) { break; /*we have a fragmented apcket. wait fot the complete one before proceeding*/ } Opcodes code = (Opcodes)BitConverter.ToUInt32(_read, (int)_rpos + MESSAGEHEAD_SIZE_LENGTH); WorldPack Packet = new WorldPack(code, packetSize); Packet.append(_read, _rpos + S2C_PACK_HEAD_SIZE, packetSize); // 将缓存中,从当前_rpos + 包头的数据给WorldPack. // 纪录发包either. // LogPacketPrintf(mSize, static_cast<uint16>(mOpcode), mSize ? Packet->contents() : NULL, 0, 0); _rpos += (UInt16)(packetSize + S2C_PACK_HEAD_SIZE); if (Packet.opcode() == Opcodes.SMSG_PONG) { _handlePong(Packet); } else if (null != _packHandler) { // push into a packet array. addEvent(Packet); } } // copy the left data to the top. if (_wpos > _rpos) { Array.Copy(_read, _rpos, _read, 0, _wpos - _rpos); } _wpos -= _rpos; // _wpos == _read.getLenth(0); _rpos = 0; Debug.Log("_onRead(While) end"); System.Diagnostics.Debug.Assert(_netStream != null); if (true == _tcpClient.Connected) { Debug.Log("_onRead to _onRead"); _netStream.BeginRead( _read, (int)_wpos, (int)(_read.Length - _wpos), new AsyncCallback(_onRead), null); Debug.Log("_onRead to _onRead2"); } // do a mess packets read to test this code. }