Ver Fonte

修复kcp一个bug,发送超过1400的包出错的问题,整理了网络层代码

tanghai há 8 anos atrás
pai
commit
9b060f32f8

+ 1 - 1
Unity/Assets/Scripts/Module/Message/Network/AChannel.cs

@@ -59,7 +59,7 @@ namespace Model
 		/// <summary>
 		/// 发送消息
 		/// </summary>
-		public abstract void Send(byte[] buffer);
+		public abstract void Send(byte[] buffer, int index, int length);
 
 		public abstract void Send(List<byte[]> buffers);
 

+ 113 - 14
Unity/Assets/Scripts/Module/Message/Network/Circularbuffer.cs

@@ -1,9 +1,12 @@
 using System;
 using System.Collections.Generic;
+using System.IO;
+using System.Net.Sockets;
+using System.Threading.Tasks;
 
 namespace Model
 {
-    public class CircularBuffer
+    public class CircularBuffer: Stream
     {
         public int ChunkSize = 8192;
 
@@ -28,7 +31,7 @@ namespace Model
             this.AddLast();
         }
 
-        public int Count
+        public override long Length
         {
             get
             {
@@ -93,38 +96,93 @@ namespace Model
             }
         }
 
-        public void RecvFrom(byte[] buffer, int count)
+		/// <summary>
+		/// 从CircularBuffer读取到stream流中
+		/// </summary>
+		/// <param name="stream"></param>
+		/// <returns></returns>
+		public async Task ReadAsync(Stream stream)
+	    {
+		    long buffLength = this.Length;
+			int sendSize = this.ChunkSize - this.FirstIndex;
+		    if (sendSize > buffLength)
+		    {
+			    sendSize = (int)buffLength;
+		    }
+			
+		    await stream.WriteAsync(this.First, this.FirstIndex, sendSize);
+
+		    this.FirstIndex += sendSize;
+		    if (this.FirstIndex == this.ChunkSize)
+		    {
+			    this.FirstIndex = 0;
+			    this.RemoveFirst();
+		    }
+		}
+
+		/// <summary>
+		/// 从stream流写到CircularBuffer中
+		/// </summary>
+		/// <param name="stream"></param>
+		/// <returns></returns>
+		public async Task<int> WriteAsync(Stream stream)
+	    {
+		    int size = this.ChunkSize - this.LastIndex;
+			
+		    int n = await stream.ReadAsync(this.Last, this.LastIndex, size);
+
+		    if (n == 0)
+		    {
+			    return 0;
+		    }
+
+		    this.LastIndex += n;
+
+		    if (this.LastIndex == this.ChunkSize)
+		    {
+			    this.AddLast();
+			    this.LastIndex = 0;
+		    }
+
+		    return n;
+	    }
+
+        public override int Read(byte[] buffer, int offset, int count)
         {
-            if (this.Count < count)
+	        if (buffer.Length < offset + count)
+	        {
+		        throw new Exception($"bufferList length < coutn, buffer length: {buffer.Length} {offset} {count}");
+	        }
+
+	        long length = this.Length;
+			if (length < count)
             {
-                throw new Exception($"bufferList size < n, bufferList: {this.Count} buffer length: {buffer.Length} {count}");
+	            count = (int)length;
             }
 
-	        if (buffer.Length < count)
-	        {
-				throw new Exception($"bufferList length < coutn, buffer length: {buffer.Length} {count}");
-	        }
             int alreadyCopyCount = 0;
             while (alreadyCopyCount < count)
             {
                 int n = count - alreadyCopyCount;
-                if (ChunkSize - this.FirstIndex > n)
+				if (ChunkSize - this.FirstIndex > n)
                 {
-                    Array.Copy(this.First, this.FirstIndex, buffer, alreadyCopyCount, n);
+                    Array.Copy(this.First, this.FirstIndex, buffer, alreadyCopyCount + offset, n);
                     this.FirstIndex += n;
                     alreadyCopyCount += n;
                 }
                 else
                 {
-                    Array.Copy(this.First, this.FirstIndex, buffer, alreadyCopyCount, ChunkSize - this.FirstIndex);
+                    Array.Copy(this.First, this.FirstIndex, buffer, alreadyCopyCount + offset, ChunkSize - this.FirstIndex);
                     alreadyCopyCount += ChunkSize - this.FirstIndex;
                     this.FirstIndex = 0;
                     this.RemoveFirst();
                 }
             }
+
+	        return count;
         }
 
-        public void SendTo(byte[] buffer)
+        public void Write(byte[] buffer)
         {
             int alreadyCopyCount = 0;
             while (alreadyCopyCount < buffer.Length)
@@ -151,7 +209,7 @@ namespace Model
             }
         }
 
-        public void SendTo(byte[] buffer, int offset, int count)
+        public override void Write(byte[] buffer, int offset, int count)
         {
             int alreadyCopyCount = 0;
             while (alreadyCopyCount < count)
@@ -177,5 +235,46 @@ namespace Model
                 }
             }
         }
+
+	    public override void Flush()
+	    {
+		    throw new NotImplementedException();
+		}
+
+	    public override long Seek(long offset, SeekOrigin origin)
+	    {
+			throw new NotImplementedException();
+	    }
+
+	    public override void SetLength(long value)
+	    {
+		    throw new NotImplementedException();
+		}
+
+	    public override bool CanRead
+	    {
+		    get
+		    {
+			    return true;
+		    }
+	    }
+
+	    public override bool CanSeek
+	    {
+		    get
+		    {
+			    return false;
+		    }
+	    }
+
+	    public override bool CanWrite
+	    {
+		    get
+		    {
+			    return true;
+		    }
+	    }
+
+	    public override long Position { get; set; }
     }
 }

+ 42 - 33
Unity/Assets/Scripts/Module/Message/Network/KCP/KChannel.cs

@@ -7,6 +7,20 @@ using System.Threading.Tasks;
 
 namespace Model
 {
+	public struct WaitSendBuffer
+	{
+		public byte[] Bytes;
+		public int Index;
+		public int Length;
+
+		public WaitSendBuffer(byte[] bytes, int index, int length)
+		{
+			this.Bytes = bytes;
+			this.Index = index;
+			this.Length = length;
+		}
+	}
+
 	public class KChannel: AChannel
 	{
 		private UdpClient socket;
@@ -14,7 +28,7 @@ namespace Model
 		private Kcp kcp;
 
 		private readonly CircularBuffer recvBuffer = new CircularBuffer(8192);
-		private readonly Queue<byte[]> sendBuffer = new Queue<byte[]>();
+		private readonly Queue<WaitSendBuffer> sendBuffer = new Queue<WaitSendBuffer>();
 
 		private readonly PacketParser parser;
 		private bool isConnected;
@@ -24,7 +38,7 @@ namespace Model
 
 		private uint lastRecvTime;
 
-		private readonly byte[] cacheBytes = new byte[1400];
+		private readonly byte[] cacheBytes = new byte[ushort.MaxValue];
 
 		public uint Conn;
 
@@ -156,8 +170,8 @@ namespace Model
 				{
 					break;
 				}
-				byte[] buffer = this.sendBuffer.Dequeue();
-				this.KcpSend(buffer);
+				WaitSendBuffer buffer = this.sendBuffer.Dequeue();
+				this.KcpSend(buffer.Bytes, buffer.Index, buffer.Length);
 			}
 		}
 
@@ -175,80 +189,75 @@ namespace Model
 					this.OnError(this, SocketError.NetworkReset);
 					return;
 				}
-				int count = this.kcp.Recv(cacheBytes);
+				int count = this.kcp.Recv(this.cacheBytes);
 				if (count <= 0)
 				{
 					return;
 				}
-				
-				// 收到的数据放入缓冲区
-				this.recvBuffer.SendTo(this.cacheBytes, 0, count);
 
 				lastRecvTime = timeNow;
 
+				// 收到的数据放入缓冲区
+				byte[] sizeBuffer = BitConverter.GetBytes((ushort)count);
+				this.recvBuffer.Write(sizeBuffer, 0, sizeBuffer.Length);
+				this.recvBuffer.Write(cacheBytes, 0, count);
+
 				if (this.recvTcs != null)
 				{
 					bool isOK = this.parser.Parse();
 					if (isOK)
 					{
-						Packet packet = this.parser.GetPacket();
-
+						Packet pkt = this.parser.GetPacket();
 						var tcs = this.recvTcs;
 						this.recvTcs = null;
-						tcs.SetResult(packet);
+						tcs.SetResult(pkt);
 					}
 				}
 			}
 		}
-		
+
 		public void Output(byte[] bytes, int count)
 		{
 			this.socket.Send(bytes, count, this.remoteEndPoint);
 		}
 
-		private void KcpSend(byte[] buffers)
+		private void KcpSend(byte[] buffers, int index, int length)
 		{
-			this.kcp.Send(buffers);
+			this.kcp.Send(buffers, index, length);
 			this.GetService().AddToUpdate(this.Id);
 		}
-		
-		public override void Send(byte[] buffer)
+
+		public override void Send(byte[] buffer, int index, int length)
 		{
-			byte[] size = BitConverter.GetBytes((ushort)buffer.Length);
 			if (isConnected)
 			{
-				this.KcpSend(size);
-				this.KcpSend(buffer);
+				this.KcpSend(buffer, index, length);
 				return;
 			}
-			this.sendBuffer.Enqueue(size);
-			this.sendBuffer.Enqueue(buffer);
+			this.sendBuffer.Enqueue(new WaitSendBuffer(buffer, index, length));
 		}
 
 		public override void Send(List<byte[]> buffers)
 		{
 			ushort size = (ushort)buffers.Select(b => b.Length).Sum();
-			byte[] sizeBuffer = BitConverter.GetBytes(size);
-			if (isConnected)
+			byte[] bytes;
+			if (!this.isConnected)
 			{
-				this.KcpSend(sizeBuffer);
+				bytes = this.cacheBytes;
 			}
 			else
 			{
-				this.sendBuffer.Enqueue(sizeBuffer);
+				bytes = new byte[size];
 			}
 
+			int index = 0;
 			foreach (byte[] buffer in buffers)
 			{
-				if (isConnected)
-				{
-					this.KcpSend(buffer);
-				}
-				else
-				{
-					this.sendBuffer.Enqueue(buffer);
-				}
+				Array.Copy(buffer, 0, bytes, index, buffer.Length);
+				index += buffer.Length;
 			}
+
+			Send(bytes, 0, size);
 		}
 
 		public override Task<Packet> Recv()

+ 53 - 48
Unity/Assets/Scripts/Module/Message/Network/KCP/Kcp.cs

@@ -41,8 +41,8 @@ public class Kcp
 	/* encode 16 bits unsigned int (lsb) */
 	public static int ikcp_encode16u(byte[] p, int offset, UInt16 w)
 	{
-		p[0 + offset] = (byte) (w >> 0);
-		p[1 + offset] = (byte) (w >> 8);
+		p[0 + offset] = (byte)(w >> 0);
+		p[1 + offset] = (byte)(w >> 8);
 		return 2;
 	}
 
@@ -51,7 +51,7 @@ public class Kcp
 	{
 		UInt16 result = 0;
 		result |= p[0 + offset];
-		result |= (UInt16) (p[1 + offset] << 8);
+		result |= (UInt16)(p[1 + offset] << 8);
 		c = result;
 		return 2;
 	}
@@ -59,10 +59,10 @@ public class Kcp
 	/* encode 32 bits unsigned int (lsb) */
 	public static int ikcp_encode32u(byte[] p, int offset, UInt32 l)
 	{
-		p[0 + offset] = (byte) (l >> 0);
-		p[1 + offset] = (byte) (l >> 8);
-		p[2 + offset] = (byte) (l >> 16);
-		p[3 + offset] = (byte) (l >> 24);
+		p[0 + offset] = (byte)(l >> 0);
+		p[1 + offset] = (byte)(l >> 8);
+		p[2 + offset] = (byte)(l >> 16);
+		p[3 + offset] = (byte)(l >> 24);
 		return 4;
 	}
 
@@ -71,9 +71,9 @@ public class Kcp
 	{
 		UInt32 result = 0;
 		result |= p[0 + offset];
-		result |= (UInt32) (p[1 + offset] << 8);
-		result |= (UInt32) (p[2 + offset] << 16);
-		result |= (UInt32) (p[3 + offset] << 24);
+		result |= (UInt32)(p[1 + offset] << 8);
+		result |= (UInt32)(p[2 + offset] << 16);
+		result |= (UInt32)(p[3 + offset] << 24);
 		c = result;
 		return 4;
 	}
@@ -127,12 +127,12 @@ public class Kcp
 
 	private static UInt32 _imin_(UInt32 a, UInt32 b)
 	{
-		return a <= b? a : b;
+		return a <= b ? a : b;
 	}
 
 	private static UInt32 _imax_(UInt32 a, UInt32 b)
 	{
-		return a >= b? a : b;
+		return a >= b ? a : b;
 	}
 
 	private static UInt32 _ibound_(UInt32 lower, UInt32 middle, UInt32 upper)
@@ -142,7 +142,7 @@ public class Kcp
 
 	private static Int32 _itimediff(UInt32 later, UInt32 earlier)
 	{
-		return (Int32) (later - earlier);
+		return (Int32)(later - earlier);
 	}
 
 	// KCP Segment Definition
@@ -172,13 +172,13 @@ public class Kcp
 			var offset_ = offset;
 
 			offset += ikcp_encode32u(ptr, offset, conv);
-			offset += ikcp_encode8u(ptr, offset, (byte) cmd);
-			offset += ikcp_encode8u(ptr, offset, (byte) frg);
-			offset += ikcp_encode16u(ptr, offset, (UInt16) wnd);
+			offset += ikcp_encode8u(ptr, offset, (byte)cmd);
+			offset += ikcp_encode8u(ptr, offset, (byte)frg);
+			offset += ikcp_encode16u(ptr, offset, (UInt16)wnd);
 			offset += ikcp_encode32u(ptr, offset, ts);
 			offset += ikcp_encode32u(ptr, offset, sn);
 			offset += ikcp_encode32u(ptr, offset, una);
-			offset += ikcp_encode32u(ptr, offset, (UInt32) data.Length);
+			offset += ikcp_encode32u(ptr, offset, (UInt32)data.Length);
 
 			return offset - offset_;
 		}
@@ -336,17 +336,22 @@ public class Kcp
 	}
 
 	// user/upper level send, returns below zero for error
-	public int Send(byte[] buffer)
+	public int Send(byte[] bytes, int index, int length)
 	{
-		if (0 == buffer.Length)
+		if (0 == bytes.Length)
 			return -1;
 
+		if (length == 0)
+		{
+			return -1;
+		}
+
 		var count = 0;
 
-		if (buffer.Length < mss)
+		if (length < mss)
 			count = 1;
 		else
-			count = (int) (buffer.Length + mss - 1) / (int) mss;
+			count = (int)(length + mss - 1) / (int)mss;
 
 		if (255 < count)
 			return -2;
@@ -359,15 +364,15 @@ public class Kcp
 		for (var i = 0; i < count; i++)
 		{
 			var size = 0;
-			if (buffer.Length - offset > mss)
-				size = (int) mss;
+			if (length - offset > mss)
+				size = (int)mss;
 			else
-				size = buffer.Length - offset;
+				size = length - offset;
 
 			var seg = new Segment(size);
-			Array.Copy(buffer, offset, seg.data, 0, size);
+			Array.Copy(bytes, offset + index, seg.data, 0, size);
 			offset += size;
-			seg.frg = (UInt32) (count - i - 1);
+			seg.frg = (UInt32)(count - i - 1);
 			snd_queue = append(snd_queue, seg);
 		}
 
@@ -379,23 +384,23 @@ public class Kcp
 	{
 		if (0 == rx_srtt)
 		{
-			rx_srtt = (UInt32) rtt;
-			rx_rttval = (UInt32) rtt / 2;
+			rx_srtt = (UInt32)rtt;
+			rx_rttval = (UInt32)rtt / 2;
 		}
 		else
 		{
-			Int32 delta = (Int32) ((UInt32) rtt - rx_srtt);
+			Int32 delta = (Int32)((UInt32)rtt - rx_srtt);
 			if (0 > delta)
 				delta = -delta;
 
-			rx_rttval = (3 * rx_rttval + (uint) delta) / 4;
-			rx_srtt = (UInt32) ((7 * rx_srtt + rtt) / 8);
+			rx_rttval = (3 * rx_rttval + (uint)delta) / 4;
+			rx_srtt = (UInt32)((7 * rx_srtt + rtt) / 8);
 			if (rx_srtt < 1)
 				rx_srtt = 1;
 		}
 
-		var rto = (int) (rx_srtt + _imax_(1, 4 * rx_rttval));
-		rx_rto = _ibound_(rx_minrto, (UInt32) rto, IKCP_RTO_MAX);
+		var rto = (int)(rx_srtt + _imax_(1, 4 * rx_rttval));
+		rx_rto = _ibound_(rx_minrto, (UInt32)rto, IKCP_RTO_MAX);
 	}
 
 	private void shrink_buf()
@@ -479,7 +484,7 @@ public class Kcp
 				this.rcv_buf = append(new Segment[1] { newseg }, this.rcv_buf);
 			else
 				this.rcv_buf = append(slice(this.rcv_buf, 0, after_idx + 1),
-				                      append(new Segment[1] { newseg }, slice(this.rcv_buf, after_idx + 1, this.rcv_buf.Length)));
+									  append(new Segment[1] { newseg }, slice(this.rcv_buf, after_idx + 1, this.rcv_buf.Length)));
 
 		// move available data from rcv_buf -> rcv_queue
 		var count = 0;
@@ -570,7 +575,7 @@ public class Kcp
 					ack_push(sn, ts);
 					if (_itimediff(sn, rcv_nxt) >= 0)
 					{
-						var seg = new Segment((int) length);
+						var seg = new Segment((int)length);
 						seg.conv = conv_;
 						seg.cmd = cmd;
 						seg.frg = frg;
@@ -601,7 +606,7 @@ public class Kcp
 				return -3;
 			}
 
-			offset += (int) length;
+			offset += (int)length;
 		}
 
 		if (_itimediff(snd_una, s_una) > 0)
@@ -634,7 +639,7 @@ public class Kcp
 	private Int32 wnd_unused()
 	{
 		if (rcv_queue.Length < rcv_wnd)
-			return (int) this.rcv_wnd - rcv_queue.Length;
+			return (int)this.rcv_wnd - rcv_queue.Length;
 		return 0;
 	}
 
@@ -652,7 +657,7 @@ public class Kcp
 		var seg = new Segment(0);
 		seg.conv = conv;
 		seg.cmd = IKCP_CMD_ACK;
-		seg.wnd = (UInt32) wnd_unused();
+		seg.wnd = (UInt32)wnd_unused();
 		seg.una = rcv_nxt;
 
 		// flush acknowledges
@@ -703,7 +708,7 @@ public class Kcp
 		if ((probe & IKCP_ASK_SEND) != 0)
 		{
 			seg.cmd = IKCP_CMD_WASK;
-			if (offset + IKCP_OVERHEAD > (int) mtu)
+			if (offset + IKCP_OVERHEAD > (int)mtu)
 			{
 				output(buffer, offset);
 				//Array.Clear(buffer, 0, offset);
@@ -745,7 +750,7 @@ public class Kcp
 			this.snd_queue = slice(this.snd_queue, count, this.snd_queue.Length);
 
 		// calculate resent
-		var resent = (UInt32) fastresend;
+		var resent = (UInt32)fastresend;
 		if (fastresend <= 0)
 			resent = 0xffffffff;
 		var rtomin = rx_rto >> 3;
@@ -914,9 +919,9 @@ public class Kcp
 		if (tm_packet >= tm_flush_)
 			minimal = tm_flush_;
 		if (minimal >= interval)
-			minimal = (int) interval;
+			minimal = (int)interval;
 
-		return current_ + (UInt32) minimal;
+		return current_ + (UInt32)minimal;
 	}
 
 	// change MTU size, default is 1400
@@ -929,7 +934,7 @@ public class Kcp
 		if (null == buffer_)
 			return -2;
 
-		mtu = (UInt32) mtu_;
+		mtu = (UInt32)mtu_;
 		mss = mtu - IKCP_OVERHEAD;
 		buffer = buffer_;
 		return 0;
@@ -941,7 +946,7 @@ public class Kcp
 			interval_ = 5000;
 		else if (interval_ < 10)
 			interval_ = 10;
-		interval = (UInt32) interval_;
+		interval = (UInt32)interval_;
 		return 0;
 	}
 
@@ -954,7 +959,7 @@ public class Kcp
 	{
 		if (nodelay_ > 0)
 		{
-			nodelay = (UInt32) nodelay_;
+			nodelay = (UInt32)nodelay_;
 			if (nodelay_ != 0)
 				rx_minrto = IKCP_RTO_NDL;
 			else
@@ -967,7 +972,7 @@ public class Kcp
 				interval_ = 5000;
 			else if (interval_ < 10)
 				interval_ = 10;
-			interval = (UInt32) interval_;
+			interval = (UInt32)interval_;
 		}
 
 		if (resend_ >= 0)
@@ -983,10 +988,10 @@ public class Kcp
 	public int WndSize(int sndwnd, int rcvwnd)
 	{
 		if (sndwnd > 0)
-			snd_wnd = (UInt32) sndwnd;
+			snd_wnd = (UInt32)sndwnd;
 
 		if (rcvwnd > 0)
-			rcv_wnd = (UInt32) rcvwnd;
+			rcv_wnd = (UInt32)rcvwnd;
 		return 0;
 	}
 

+ 4 - 4
Unity/Assets/Scripts/Module/Message/Network/TCP/PacketParser.cs

@@ -75,13 +75,13 @@ namespace Model
 				switch (this.state)
 				{
 					case ParserState.PacketSize:
-						if (this.buffer.Count < 2)
+						if (this.buffer.Length < 2)
 						{
 							finish = true;
 						}
 						else
 						{
-							this.buffer.RecvFrom(this.packet.Bytes, 2);
+							this.buffer.Read(this.packet.Bytes, 0, 2);
 							this.packetSize = BitConverter.ToUInt16(this.packet.Bytes, 0);
 							if (packetSize > 60000)
 							{
@@ -91,13 +91,13 @@ namespace Model
 						}
 						break;
 					case ParserState.PacketBody:
-						if (this.buffer.Count < this.packetSize)
+						if (this.buffer.Length < this.packetSize)
 						{
 							finish = true;
 						}
 						else
 						{
-							this.buffer.RecvFrom(this.packet.Bytes, this.packetSize);
+							this.buffer.Read(this.packet.Bytes, 0, this.packetSize);
 							this.packet.Length = this.packetSize;
 							this.isOK = true;
 							this.state = ParserState.PacketSize;

+ 11 - 30
Unity/Assets/Scripts/Module/Message/Network/TCP/TChannel.cs

@@ -86,15 +86,15 @@ namespace Model
 			this.StartRecv();
 		}
 
-		public override void Send(byte[] buffer)
+		public override void Send(byte[] buffer, int index, int length)
 		{
 			if (this.IsDisposed)
 			{
 				throw new Exception("TChannel已经被Dispose, 不能发送消息");
 			}
 			byte[] size = BitConverter.GetBytes((ushort)buffer.Length);
-			this.sendBuffer.SendTo(size);
-			this.sendBuffer.SendTo(buffer);
+			this.sendBuffer.Write(size, 0, size.Length);
+			this.sendBuffer.Write(buffer, index, length);
 			if (this.isConnected)
 			{
 				this.StartSend();
@@ -109,10 +109,10 @@ namespace Model
 			}
 			ushort size = (ushort)buffers.Select(b => b.Length).Sum();
 			byte[] sizeBuffer = BitConverter.GetBytes(size);
-			this.sendBuffer.SendTo(sizeBuffer);
+			this.sendBuffer.Write(sizeBuffer, 0, sizeBuffer.Length);
 			foreach (byte[] buffer in buffers)
 			{
-				this.sendBuffer.SendTo(buffer);
+				this.sendBuffer.Write(buffer, 0, buffer.Length);
 			}
 			if (this.isConnected)
 			{
@@ -143,33 +143,22 @@ namespace Model
 					}
 
 					// 没有数据需要发送
-					if (this.sendBuffer.Count == 0)
+					long buffLength = this.sendBuffer.Length;
+					if (buffLength == 0)
 					{
 						this.isSending = false;
 						return;
 					}
 
 					this.isSending = true;
-
-					int sendSize = sendBuffer.ChunkSize - this.sendBuffer.FirstIndex;
-					if (sendSize > this.sendBuffer.Count)
-					{
-						sendSize = this.sendBuffer.Count;
-					}
-
+					
 					NetworkStream stream = this.tcpClient.GetStream();
 					if (!stream.CanWrite)
 					{
 						return;
 					}
-					await stream.WriteAsync(this.sendBuffer.First, this.sendBuffer.FirstIndex, sendSize);
 
-					this.sendBuffer.FirstIndex += sendSize;
-					if (this.sendBuffer.FirstIndex == sendBuffer.ChunkSize)
-					{
-						this.sendBuffer.FirstIndex = 0;
-						this.sendBuffer.RemoveFirst();
-					}
+					await this.sendBuffer.ReadAsync(stream);
 				}
 			}
 			catch (Exception e)
@@ -189,29 +178,21 @@ namespace Model
 					{
 						return;
 					}
-					int size = this.recvBuffer.ChunkSize - this.recvBuffer.LastIndex;
 
 					NetworkStream stream = this.tcpClient.GetStream();
 					if (!stream.CanRead)
 					{
 						return;
 					}
-					int n = await stream.ReadAsync(this.recvBuffer.Last, this.recvBuffer.LastIndex, size);
 
+					int n = await this.recvBuffer.WriteAsync(stream);
+					
 					if (n == 0)
 					{
 						this.OnError(this, SocketError.NetworkReset);
 						return;
 					}
 
-					this.recvBuffer.LastIndex += n;
-
-					if (this.recvBuffer.LastIndex == this.recvBuffer.ChunkSize)
-					{
-						this.recvBuffer.AddLast();
-						this.recvBuffer.LastIndex = 0;
-					}
-
 					if (this.recvTcs != null)
 					{
 						bool isOK = this.parser.Parse();

+ 7 - 4
Unity/Unity.csproj

@@ -12,12 +12,15 @@
     <ProjectTypeGuids>{E097FAD1-6243-4DAD-9C02-E9B9EFC3FFC1};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
     <TargetFrameworkIdentifier>.NETFramework</TargetFrameworkIdentifier>
     <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
-    <TargetFrameworkProfile></TargetFrameworkProfile>
-    <CompilerResponseFile></CompilerResponseFile>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
+    <CompilerResponseFile>
+    </CompilerResponseFile>
     <UnityProjectType>Game:1</UnityProjectType>
     <UnityBuildTarget>StandaloneWindows:5</UnityBuildTarget>
     <UnityVersion>2017.1.1p4</UnityVersion>
-    <RootNamespace></RootNamespace>
+    <RootNamespace>
+    </RootNamespace>
     <LangVersion>6</LangVersion>
   </PropertyGroup>
   <PropertyGroup>
@@ -774,4 +777,4 @@
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <Target Name="GenerateTargetFrameworkMonikerAttribute" />
-</Project>
+</Project>