/// <summary> /// 对客户端传过来的数据类型进行封包和解包, object支持unity特定的类型: Vector2, Vector3 /// </summary> /// <param name="buffer">Buffer.</param> /// <param name="objs">Objects.</param> public void encode(TNBuffer buffer, params object[] objs) { if (objs == null || objs.Length == 0) return; BinaryWriter bw = buffer.BeginWriting(true); for (int b = 0, bmax = objs.Length; b < bmax; ++b) { object obj = objs[b]; if (obj != null && !WriteObject(bw, obj)) { Debug.LogError("Unable to write type " + obj.GetType()); } } }
/// <summary> /// See if the received packet can be processed and split it up into different ones. /// </summary> bool ProcessBuffer (int bytes) { if (mReceiveBuffer == null) { // Create a new packet buffer mReceiveBuffer = TNBuffer.Create(); mReceiveBuffer.BeginWriting(false).Write(mTemp, 0, bytes); } else { // Append this data to the end of the last used buffer mReceiveBuffer.BeginWriting(true).Write(mTemp, 0, bytes); } for (int available = mReceiveBuffer.size - mOffset; available >= 4; ) { // Figure out the expected size of the packet if (mExpected == 0) { mExpected = mReceiveBuffer.PeekInt(mOffset); if (mExpected == -1) break; if (mExpected == 0) { Close(true); return false; } } // The first 4 bytes of any packet always contain the number of bytes in that packet available -= 4; // If the entire packet is present if (available == mExpected) { if (onDebug != null) { onDebug(this.serverName, "OnReceive, bytes: " + mExpected); } // Reset the position to the beginning of the packet mReceiveBuffer.BeginReading(mOffset + 4); // This packet is now ready to be processed lock (mIn) mIn.Enqueue(mReceiveBuffer); mReceiveBuffer = null; mExpected = 0; mOffset = 0; if (null != this.onReceivePack) { this.onReceivePack(); } break; } else if (available > mExpected) { // There is more than one packet. Extract this packet fully. int realSize = mExpected + 4; TNBuffer temp = TNBuffer.Create(); // Extract the packet and move past its size component temp.BeginWriting(false).Write(mReceiveBuffer.buffer, mOffset, realSize); temp.BeginReading(4); // This packet is now ready to be processed lock (mIn) mIn.Enqueue(temp); // Skip this packet available -= mExpected; mOffset += realSize; mExpected = 0; if (null != this.onReceivePack) { this.onReceivePack(); } } else break; } return true; }
/// <summary> /// Extract the first incoming packet. /// </summary> public bool ReceivePacket (out TNBuffer buffer) { if (mIn.Count != 0) { lock (mIn) { buffer = mIn.Dequeue(); return true; } } buffer = null; return false; }
/// <summary> /// Send the specified packet. Marks the buffer as used. /// </summary> public void SendTcpPacket (TNBuffer buffer) { buffer.MarkAsUsed(); if (mSocket != null && mSocket.Connected) { buffer.BeginReading(); lock (mOut) { mOut.Enqueue(buffer); if (mOut.Count == 1) { try { if (onDebug != null) { onDebug(this.serverName, "SendTcpPacket, size: " + buffer.size); } // If it's the first packet, let's begin the send process lastSendTime = DateTime.Now.Ticks / 10000; mSocket.BeginSend(buffer.buffer, buffer.position, buffer.size, SocketFlags.None, OnSend, buffer); } catch (System.Exception ex) { Error(ex.Message); Close(false); Release(); } } } } else buffer.Recycle(); }
/// <summary> /// Send the outgoing buffer. /// </summary> public void EndSend () { mBuffer.EndPacket(); SendTcpPacket(mBuffer); mBuffer = null; }
/// <summary> /// Begin sending a new packet to the server. /// </summary> public BinaryWriter BeginSend (int packetID) { mBuffer = TNBuffer.Create(false); return mBuffer.BeginPacket(packetID); }
/// <summary> /// Close the connection. /// </summary> public void Close (bool notify) { stage = Stage.NotConnected; if (mReceiveBuffer != null) { mReceiveBuffer.Recycle(); mReceiveBuffer = null; } if (mSocket != null) { try { if (mSocket.Connected) mSocket.Shutdown(SocketShutdown.Both); mSocket.Close(); } catch (System.Exception) {} mSocket = null; if (notify) { if (this.onDisconnected != null) { this.onDisconnected(this.serverName, TNErrorCode.DISCONNECT); } } } }
/// <summary> /// Initializes a new instance of the <see cref="IPackage"/> class. /// </summary> /// <param name="buffer">Buffer.</param> public IPackage(TNBuffer buffer) { m_buffer = buffer; }
/// <summary> /// Ends the read. /// </summary> public void EndRead() { if (m_reader != null) { m_reader = null; } if (m_buffer != null) { m_buffer.Recycle(); m_buffer = null; } }
/// <summary> /// Create a new buffer, reusing an old one if possible. /// </summary> static public TNBuffer Create (bool markAsUsed) { TNBuffer b = null; if (mPool.Count == 0) { b = new TNBuffer(); //Console.WriteLine("NEW"); } else { lock (mPool) { if (mPool.Count != 0) { b = mPool[0]; mPool.Remove(b); b.mInPool = false; } else { b = new TNBuffer(); } } } b.mCounter = markAsUsed ? 1 : 0; return b; }
/// <summary> /// Copy the contents of this buffer into the target one, trimming away unused space. /// </summary> public void CopyTo (TNBuffer target) { BinaryWriter w = target.BeginWriting(false); int bytes = size; if (bytes > 0) w.Write(buffer, position, bytes); target.EndWriting(); }