protected internal override bool Feed(byte[] data, int cnt, IPEndPoint ep) { if (_Conv == 0) { // this means the conv has not been accepted by client. var conv = ReadConv(data, cnt); if (conv == 0) { // wrong packet. return(false); } else if (conv == 1) { // the unaccepted connection var guid = ReadGUID(data, cnt); if (guid == Guid.Empty) { if (EP != null && EP.Equals(ep)) { // this means the ack-packet or something else. return(_KCP.kcp_input(data, cnt) == 0); } else { // client should provide a guid for new connection return(false); } } else { if (_PendingGUID == Guid.Empty) { // accept this connection. bind this connection with the guid. if (_KCP.kcp_input(data, cnt) == 0) { _PendingGUID = guid; EP = ep; // send the pending conv-id to client. byte[] buffer = BufferPool.GetBufferFromPool(); if (BitConverter.IsLittleEndian) { var pconv = _PendingConv; for (int i = 0; i < 4; ++i) { buffer[i] = (byte)((pconv >> (i * 8)) & 0xFF); } } else { var pconv = _PendingConv; for (int i = 0; i < 4; ++i) { buffer[i] = (byte)((pconv >> ((3 - i) * 8)) & 0xFF); } } _KCP.kcp_send(buffer, 4); BufferPool.ReturnBufferToPool(buffer); _Connected = true; return(true); } else { return(false); } } else { // check the guid. if (_PendingGUID == guid) { if (_KCP.kcp_input(data, cnt) == 0) { if (!ep.Equals(EP)) { // check the ep changed? EP = ep; } return(true); } else { return(false); } } else { return(false); } } } } else { // the first packet from accepted connection? if (conv == _PendingConv) { // the first packet from accepted connection! // change the kcp to real conv-id. _Conv = conv; _KCP.kcp_release(); _KCP = KCPLib.kcp_create(conv, (IntPtr)_InfoHandle); _KCP.kcp_setoutput(Func_KCPOutput); _KCP.kcp_nodelay(1, 10, 2, 1); // set minrto to 10? if (!ep.Equals(EP)) { // check the ep changed? EP = ep; } // Feed the data. return(_KCP.kcp_input(data, cnt) == 0); } else { // this packet is for other connection. return(false); } } } else { // the normal connection. return(base.Feed(data, cnt, ep)); } }