Пример #1
0
 public KcpNetPack Recv()
 {
     if (_recvPacks.ContainsKey(_recvIdx))
     {
         _recvAckIdx = _recvIdx;
         KcpNetPack pack = _recvPacks[_recvIdx];
         _recvPacks.Remove(_recvIdx);//清理内存
         _recvIdx++;
         //SetHadCheck("Recv");
         return(pack);
     }
     if (_sendNewIdx - _recvIdx > _range)
     {
         Debug.Log("Recv==>对方最新的发送序号:" + _sendNewIdx + ",正在接收处理的包序号:" + _recvIdx + ",R:" + _range);
         _reRecvTime++;
         if (_lastReRecvIdx != _recvIdx || _reRecvTime > RE_RECV_ACK_TIME)
         {
             _lastReRecvIdx = _recvIdx;
             _reRecvTime    = 0;
             ReRecvAckIdx(_recvIdx);
         }
         if (_sendNewIdx - _recvIdx > MAX_DIS_CONNECTED_FS_NUM)
         {
             Disconnect("Recv");
         }
     }
     return(null);
 }
Пример #2
0
 public void Disconnect(string sReason)
 {
     Debug.LogFormat("NetUdpSocket Disconnect:{0}", sReason);
     if (sReason != "Server")
     {
         Kcp_DisConnect msg = new Kcp_DisConnect();
         msg.Type = (int)Kcp_Net_Type.DscNormal;
         KcpNetPack pack = KcpNetPack.SerializeToPack(msg, (ushort)Kcp_MsgID.DisConnected);
         SocketSend(pack);
     }
     isConnected   = false;
     isConnectting = false;
     try
     {
         //关闭线程
         ConnectReceiveThread_Stop();
         //最后关闭socket
         if (socket != null)
         {
             socket.Close();
         }
     }
     catch (Exception e)
     {
         Debug.LogErrorFormat("Disconnect:{0}", e);
     }
     finally
     {
         lock (netEventList)
         {
             netEventList.Enqueue(NetworkEvent.disconnected);
         }
     }
     //Debug.Log("继续运行==============================>");
 }
Пример #3
0
        private void ReRecvAckIdx(int notAckIdx)
        {
            int iEndNotAckIdx = notAckIdx;

            for (int i = 1; i < MAX_DIS_CONNECTED_FS_NUM; i++)
            {
                if ((notAckIdx + i) > _sendNewIdx)
                {
                    break;                                          //大于对方最新的发送序号
                }
                if (_recvPacks.ContainsKey(notAckIdx + i))
                {
                    break;                                          //已经有数据了
                }
                iEndNotAckIdx++;
            }
            Debug.Log("请求对方重发非ACK序号:" + notAckIdx + "-" + iEndNotAckIdx);
            Kcp_NotAckIndex msg = new Kcp_NotAckIndex();

            msg.Startindex = notAckIdx;
            msg.Endindex   = iEndNotAckIdx;

            KcpNetPack pack = KcpNetPack.SerializeToPack(msg, (ushort)Kcp_MsgID.NotAckIndex);

            SocketSend(pack);
            _lastRecvNotAckTime++;
            if (_lastRecvNotAckIdx != notAckIdx || _lastRecvNotAckTime > RE_RECV_NOT_ACK_TIME)
            {
                _lastRecvNotAckIdx  = notAckIdx;
                _lastRecvNotAckTime = 0;
                UpCacheFSTime();
            }
        }
Пример #4
0
        public void Send(KcpNetPack pack)
        {
            _sendIdx++;
            var fsdata = pack.Assembly();

            _sendPacks.Add(_sendIdx, fsdata.Bytes);
            RcpPackSendData(_sendIdx, _range);
            SetHadCheck("Send");
        }
Пример #5
0
        //public T Deserialize<T>()
        //{
        //    using (var ms = new MemoryStream(this.BodyBuffer.Bytes, 0, this.BodyBuffer.BufSize))
        //        return ProtoBuf.Serializer.Deserialize<T>(ms);
        //}
        //void Send<T>(Protocol type, T content) where T : Google.Protobuf.IMessage
        //{
        //    GameMessage message = new GameMessage();
        //    message.Type = type;
        //    message.Data = ByteString.CopyFrom(content.ToByteArray());
        //    _UnityUdpSocket.Send(message.ToByteArray());
        //}
        public static KcpNetPack SerializeToPack <T>(T content, ushort msg_id) where T : Google.Protobuf.IMessage
        {
            int        size = content.CalculateSize();//注意检查长度不能超过  65,535-HeaderLength
            KcpNetPack pack = new KcpNetPack(msg_id, (ushort)size);

            pack.BodyBuffer = CBuffer.Create(size);
            pack.BodyBuffer.Fill(content.ToByteArray(), size);
            return(pack);
        }
Пример #6
0
        private void RcpPackSendData(int iSendIdx, int iRange)//包含了iSendIdx的iRange个包
        {
            if (!_sendPacks.ContainsKey(iSendIdx))
            {
                return;
            }
            iRange = Math.Min(iRange, iSendIdx - _sendAckIdx);
            if (iRange <= 0)
            {
                return;
            }
            // Debug.Log("RcpPackSendData=========>" + iSendIdx + ",iRange:" + iRange);
            int iTime     = iRange / MAX_DATA_CACHE + 1;
            int iStartIdx = iSendIdx - iRange;

            for (int i = 1; i <= iTime; i++)
            {
                int iSendIdx2, iRange2;
                if (iTime == i)
                {
                    iSendIdx2 = iSendIdx;
                    iRange2   = Math.Min(iRange - (i - 1) * MAX_DATA_CACHE, MAX_DATA_CACHE);
                    if (iRange2 <= 0)
                    {
                        return;
                    }
                }
                else
                {
                    iSendIdx2 = iStartIdx + MAX_DATA_CACHE * i;
                    iRange2   = MAX_DATA_CACHE;
                }
                Kcp_FsPackDatas msg = new Kcp_FsPackDatas();
                msg.Ackindex  = _recvAckIdx;
                msg.Sendindex = _sendIdx;
                for (int idx = (iSendIdx2 - iRange2 + 1); idx <= iSendIdx2; idx++)
                {
                    if (idx < 0)
                    {
                        continue;
                    }
                    if (!_sendPacks.ContainsKey(idx))
                    {
                        continue;
                    }
                    // Debug.Log("RcpPackSendData===>" + idx);
                    Kcp_OneFsPackData fsPackData = new Kcp_OneFsPackData();
                    fsPackData.Index  = idx;
                    fsPackData.Fsdata = ByteString.CopyFrom(_sendPacks[idx]);
                    msg.Fspackdata.Add(fsPackData);
                }
                //Debug.Log("RcpPackSendData=========>总序号:" + iSendIdx + ",总范围:" + iRange + ",序号" + iSendIdx2 + ",范围:" + iRange2 );
                KcpNetPack pack = KcpNetPack.SerializeToPack(msg, (ushort)Kcp_MsgID.FsInfoS);
                SocketSend(pack);
            }
        }
Пример #7
0
        public void SocketSend(KcpNetPack pack)
        {
            if (!isConnected || isConnectting)
            {
                return;
            }
            var data = pack.Assembly();

            socket.SendTo(data.Bytes, data.Length, SocketFlags.None, ipEnd);
            _lastSendTime = System.Environment.TickCount;
        }
Пример #8
0
        /*public void Flush()
         * {
         *  if (_sendAckIdx < _sendIdx && _sendAckIdx > -1)
         *  {
         *      RcpPackSendData(_sendIdx, _range);
         *  }
         *  SetHadCheck();
         * }*/

        private void SynAckStatus()
        {
            if ((System.Environment.TickCount - _lastCheckTime > SYN_ACK_TIME && !_isSynAck) || System.Environment.TickCount - _lastSendTime > MUST_SYN_ACK_TIME)
            {
                //Debug.Log("同步Ack");
                _isSynAck = true;
                Kcp_FsPackDatas msg = new Kcp_FsPackDatas();
                msg.Ackindex  = _recvAckIdx;
                msg.Sendindex = _sendIdx;
                KcpNetPack pack = KcpNetPack.SerializeToPack(msg, (ushort)Kcp_MsgID.SynAck);
                SocketSend(pack);
            }
        }
Пример #9
0
        public Queue <KcpNetPack> RecvPacks(int iMaxNum)
        {
            Queue <KcpNetPack> recvPacks = new Queue <KcpNetPack>();
            int iTime = iMaxNum;

            while (iTime > 0)
            {
                iTime--;
                KcpNetPack pack = Recv();
                if (pack == null)
                {
                    break;
                }
                recvPacks.Enqueue(pack);
            }
            return(recvPacks);
        }
Пример #10
0
 public void OnUpdate()
 {
     if (isConnectting)
     {
         if (System.Environment.TickCount - _lastCheckFailTime > (CONNECTED_FAIL_TIME * (_tryConnectTime + 1)))
         {
             _tryConnectTime++;
             if (_tryConnectTime < MAX_CONNECT_TIME)
             {
                 ConnectReceiveThread_Stop();//必须先关接收数据线程,再开.不然无法接收数据(待不需要关线程方案)
                 Kcp_Connect msg = new Kcp_Connect();
                 msg.Quickconnect = _quickConnect;
                 KcpNetPack pack = KcpNetPack.SerializeToPack(msg, (ushort)Kcp_MsgID.Connected);
                 SetHadCheck("ReConnect");
                 var data = pack.Assembly();
                 socket.SendTo(data.Bytes, data.Length, SocketFlags.None, ipEnd);
                 _lastCheckFailTime = System.Environment.TickCount;
                 Debug.LogErrorFormat("[链接失败]第{0}次尝试重新连接", _tryConnectTime);
                 ConnectReceiveThread_Start();
             }
             else
             {
                 lock (netEventList)
                 {
                     netEventList.Enqueue(NetworkEvent.connectFail);
                 }
                 Debug.LogErrorFormat("[失败]第{0}次连接", _tryConnectTime);
                 isConnectting   = false;
                 _tryConnectTime = 0;
             }
         }
     }
     lock (netEventList)
     {
         while (netEventList.Count > 0)
         {
             var e = netEventList.Dequeue();
             listener.OnEvent(e);
         }
     }
     Check();
 }
Пример #11
0
 private void TestPing()
 {
     if (OBTAIN_PING)
     {
         if (_canNextPing && System.Environment.TickCount - _lastPingTime > PING_CHECK_TIME)
         {
             _pingIdx++;
             Kcp_Ping msg = new Kcp_Ping();
             msg.Index = _pingIdx;
             KcpNetPack pack = KcpNetPack.SerializeToPack(msg, (ushort)Kcp_MsgID.PingIndex);
             SocketSend(pack);
             _lastPingTime = System.Environment.TickCount;
             _canNextPing  = false;
         }
         else if (!_canNextPing && System.Environment.TickCount - _lastPingTime > PING_CHECK_TIME * 3)
         {
             _canNextPing = true;    //恰好是测试ping丢包时候,这里做个超时重测功能
         }
     }
 }
Пример #12
0
        public void ConnectKCP(string host, int iport)
        {
            mHUDFPS = Facade.Instance.GetManager <HUDFPS>(FacadeConfig.ChildSystem_HUDFPS);
            _range  = BASE_DATA_CACHE;
            ipEnd   = new IPEndPoint(IPAddress.Parse(host), iport);
            socket  = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            //socket.Connect(ipEnd);
            IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);

            serverEnd = (EndPoint)sender;
            Kcp_Connect msg = new Kcp_Connect();

            msg.Quickconnect = _quickConnect;
            KcpNetPack pack = KcpNetPack.SerializeToPack(msg, (ushort)Kcp_MsgID.Connected);

            SetHadCheck("Connect");
            var data = pack.Assembly();

            socket.SendTo(data.Bytes, data.Length, SocketFlags.None, ipEnd);
            isConnectting      = true;
            isConnected        = false;
            _lastCheckFailTime = System.Environment.TickCount;
            ConnectReceiveThread_Start();
        }
Пример #13
0
        //==========Rcp核心算法======================================================================
        public void Input(byte[] buffer, int bufSize)
        {
            //List<NetPack> packs = DecodeBuffer(recvData, recvLen);
            //for (int i = 0; i < packs.Count; ++i)
            //    Input(packs[i]);
            int        offset1    = 0;
            int        restCount2 = bufSize;// 剩余缓存大小
            KcpNetPack pack       = new KcpNetPack();

            if (!pack.FillPack(buffer, ref offset1, ref restCount2))
            {
                return;
            }

            Kcp_MsgID msgID = (Kcp_MsgID)pack.HeadID;

            if (msgID == Kcp_MsgID.NotAckIndex)
            {
                Kcp_NotAckIndex msg = Kcp_NotAckIndex.Parser.ParseFrom(pack.BodyBuffer.Bytes);
                Debug.Log("回复对方缺失的序号:" + msg.Startindex + "-" + msg.Endindex + ",对方已确认接收成功的Ack序号:" + _sendAckIdx);
                if (_sendAckIdx >= msg.Endindex)
                {
                    return;
                }
                int iStartIndex = Math.Max(msg.Startindex, _sendAckIdx + 1);
                if (iStartIndex > msg.Endindex)
                {
                    return;
                }
                _reSendTime++;
                if (_lastReSendIdx != iStartIndex || _reSendTime > RE_SEND_ACK_TIME)
                {
                    _lastReSendIdx = iStartIndex;
                    _reSendTime    = 0;
                    RcpPackSendData(msg.Endindex, msg.Endindex - iStartIndex + 1);
                }
                _lastSendNotAckTime++;
                if (_lastSendNotAckIdx != iStartIndex || _lastSendNotAckTime > RE_SEND_NOT_ACK_TIME)
                {
                    _lastSendNotAckIdx  = iStartIndex;
                    _lastSendNotAckTime = 0;
                    UpCacheFSTime();
                }
            }
            else if (msgID == Kcp_MsgID.FsInfoS || msgID == Kcp_MsgID.SynAck)
            {
                Kcp_FsPackDatas msg = Kcp_FsPackDatas.Parser.ParseFrom(pack.BodyBuffer.Bytes);
                if (msg.Ackindex > _sendAckIdx)
                {
                    _sendAckIdx = msg.Ackindex;
                }
                if (msg.Sendindex > _sendNewIdx)
                {
                    _sendNewIdx = msg.Sendindex;
                }
                //if (msgID == Kcp_MsgID.FS_INFO_S)
                //    Debug.Log("最新的已ACK序号确认==>" + _lastSendAckIdx + ",对方已确认接收成功的Ack序号:" + _sendAckIdx + "," + msg.ackindex + ",对方最新的发送序号:" + _sendNewIdx + "," + msg.sendindex);
                //else
                //    Debug.Log("同步ACK状态==========>" + _lastSendAckIdx + ",对方已确认接收成功的Ack序号:" + _sendAckIdx + "," + msg.ackindex + ",对方最新的发送序号:" + _sendNewIdx + "," + msg.sendindex);
                for (int idx = _lastSendAckIdx; idx <= _sendAckIdx; idx++)
                {
                    _sendPacks.Remove(idx);//清理内存
                }
                _lastSendAckIdx = _sendAckIdx;

                int iMinIndex = -1;
                for (int i = 0; i < msg.Fspackdata.Count; i++)
                {
                    Kcp_OneFsPackData fsPackData = msg.Fspackdata[i];
                    //Debug.Log("*************=1==>" + fsPackData.index);
                    if (_recvPacks.ContainsKey(fsPackData.Index))
                    {
                        continue;
                    }
                    if (_recvAckIdx >= fsPackData.Index)
                    {
                        continue;
                    }
                    //Debug.Log("*************=2==>" + fsPackData.index);
                    int offset    = 0;
                    int restCount = 1024;// 剩余缓存大小
                    if (curPack2 == null)
                    {
                        curPack2 = new KcpNetPack();
                    }
                    if (curPack2.FillPack(fsPackData.Fsdata.ToByteArray(), ref offset, ref restCount))
                    {
                        if (fsPackData.Index < iMinIndex || iMinIndex == -1)
                        {
                            iMinIndex = fsPackData.Index;
                        }
                        _recvPacks[fsPackData.Index] = curPack2;
                        curPack2 = null;
                    }
                    else
                    {
                        RcpPackSendData(fsPackData.Index, 2);
                        Debug.LogErrorFormat("Input err: {0} ", fsPackData.Index);
                    }
                }
                CheckPreorderLose(iMinIndex);
                DownCacheFSTime();
            }
            else if (msgID == Kcp_MsgID.Connected || msgID == Kcp_MsgID.ReConnected)  //暂时只有一次握手
            {
                Kcp_Connect msg = Kcp_Connect.Parser.ParseFrom(pack.BodyBuffer.Bytes);
                if (_quickConnect != msg.Quickconnect)  //防重复
                {
                    lock (netEventList)
                    {
                        netEventList.Enqueue(NetworkEvent.connected);
                    }
                    _quickConnect = msg.Quickconnect;
                }
                isConnected     = true;
                isConnectting   = false;
                _tryConnectTime = 0;
                Debug.Log("链接成功:" + _quickConnect);
            }
            else if (msgID == Kcp_MsgID.ConnectedFail)  //暂时只有一次握手
            {
                lock (netEventList)
                {
                    netEventList.Enqueue(NetworkEvent.connectFail);
                }
                isConnected   = false;
                isConnectting = false;
                Debug.Log("链接失败:CONNECTED_FAIL:");
            }
            else if (msgID == Kcp_MsgID.DisConnected)  //暂时只有一次挥手
            {
                Kcp_DisConnect msg = Kcp_DisConnect.Parser.ParseFrom(pack.BodyBuffer.Bytes);
                if (msg.Type == (int)Kcp_Net_Type.DscErrAddr)
                {
                    Debug.Log("链接断开:DSC_ERR_ADDR:" + _quickConnect);
                    isConnectting = true;       //快速重连/身份重新认证/更新IP地址
                }
                else
                {
                    Disconnect("Server");
                }
                //Debug.Log("继续运行2==============================>");
            }
            else if (msgID == Kcp_MsgID.PingIndex)
            {
                Kcp_Ping msg = Kcp_Ping.Parser.ParseFrom(pack.BodyBuffer.Bytes);
                if (msg.Index == _pingIdx)
                {
                    Ping = System.Environment.TickCount - _lastPingTime;
                }
                UpdateNetInfo("");
                //Debug.Log("Ping==============================>" + Ping);
                _canNextPing = true;
            }
            else
            {
                Debug.LogErrorFormat("Input err2: {0} ", msgID);
                return;
            }
            SetHadCheck("Input");
        }
Пример #14
0
 public void SendPack(KcpNetPack pack)
 {
     Send(pack);
 }