Beispiel #1
0
        /*
         * 发送pkgs的最底层接口
         */

        private void SendPkgsEx(List <UdpPackage> _sendPkgs)
        {
            Dictionary <byte, object> param    = new Dictionary <byte, object>();
            OperationResponse         response = new OperationResponse((byte)OperationCode_Other, param);
            long nowTime = DateTime.Now.Ticks;

            ////Log.Error("====================SendPkgs:" + _sendPkgs.Count);
            int beginIdx = 1;
            int pkgCount = 0;
            int range    = 4;

            for (int i = 0; i < _sendPkgs.Count; i++)
            {
                UdpPackage sPkg = _sendPkgs[i];
                param[(byte)(beginIdx + range * i + 0)] = (long)(sPkg.channelID * 1000 + sPkg.code);
                param[(byte)(beginIdx + range * i + 1)] = sPkg.seqNo;
                param[(byte)(beginIdx + range * i + 2)] = nowTime;
                param[(byte)(beginIdx + range * i + 3)] = sPkg.msg;
                sPkg.sentCnt++;
                sPkg.sentTime = nowTime;
                sPkg.bLost    = false;
                pkgCount++;
                ////Log.Error("====================SendPkgs:" + pkgCount + " code:" + sPkg.code + " c: " + sPkg.channelID + " SeqNo:" + sPkg.seqNo + " SentTime:" + nowTime);
            }
            param[0] = pkgCount;
            //...do send...
            SendResult ret = peer.SendOperationResponse(response, sendParam);

            _sendPkgs.Clear();
        }
Beispiel #2
0
 private void OnAck(int channelID, long seqNo, long sentTime)
 {
     ////Log.Error("====================OnAck detail: channelID: " + channelID + " seqNo: " + seqNo + " sentTime:" + sentTime);
     UdpPackage[] pkgArr;
     if (pkgMatrix.TryGetValue(channelID, out pkgArr))
     {
         ChannelInfo cInfo = channelArr[channelID];
         if (cInfo.InRange(seqNo))
         {
             if (sentTime == 0)
             {
                 SetAllAckBack(channelID, seqNo);
             }
             else
             {
                 UdpPackage pkg = pkgArr[SeqnoIdx(seqNo)];
                 if (!pkg.isAckBack)
                 {
                     pkg.SetAckBacked(sentTime);
                 }
                 SetLostFlag(cInfo, pkgArr, seqNo, sentTime);
             }
             AssignSeqno(channelID, seqNo);
         }
     }
 }
Beispiel #3
0
 private void SetLostFlag(ChannelInfo cInfo, UdpPackage[] pkgs, long seqNoRecved, long sentTime)
 {
     for (long i = (seqNoRecved - 1); i >= cInfo.firstSeqno; i--)
     {
         int        idx = SeqnoIdx(i);
         UdpPackage pkg = pkgs[idx];
         if (pkg != null && !pkg.isAckBack && !pkg.bLost && pkg.sentTime < sentTime)
         {
             pkg.bLost = true;
         }
     }
 }
Beispiel #4
0
        protected void TryFindCouldApplyPkgs(long delayTime)
        {
            if (sendPkgs.Count == 0)
            {
                return;
            }
            long nowTime = DateTime.Now.Ticks;

            if (true) //找到那些适合附带一起发送的,为了合理利用mtu
            {
                foreach (var channel in channelArr.Values)
                {
                    if (channel.Empty())
                    {
                        continue;                  //当前channel为空的
                    }
                    UdpPackage[] pkgs            = pkgMatrix[channel.channelID];
                    int          curCntOfChannel = 0;
                    for (long seqIdx = channel.firstSeqno; seqIdx < channel.lastSeqno; seqIdx++)
                    {
                        if (curCntOfChannel >= 5)
                        {
                            break;
                        }
                        UdpPackage pkg = pkgs[SeqnoIdx(seqIdx)];
                        if (pkg == null)
                        {
                            continue;
                        }
                        if (pkg.sendIndex == sendIndex)
                        {
                            continue;                             //当前发送队列已经标记发送
                        }
                        //if (i < channel.firstFrame || channel.lastFrame <= i) continue; //遍历的帧号 当前channel不包含
                        if (pkg == null || pkg.isAckBack || pkg.sentTime == 0 || (pkg.sentTime + (peer.RoundTripTime + delayTime) * 10000) > nowTime)
                        {
                            continue;                                                                                                                           //如果这个刚发送不久,则不需要重发
                        }
                        ////Log.Error("----------------------- TryCouldApplyPkgs: " + pkg.channelID + " SeqNo:" + pkg.seqNo);
                        couldApplyPkgs.Add(pkg);
                        curCntOfChannel++;
                    }
                }
                if (couldApplyPkgs.Count > 0)
                {
                    ////Log.Error("----------------------- TryCouldApplyPkgs: " + couldApplyPkgs.Count);
                }
            }
        }
Beispiel #5
0
        /*
         * 尝试发送超时的
         */

        protected int TryResendTimeoutPkg(long factor1 = 0, bool useResendDelayTimeArr = true, bool forceResend = false)
        {
            long nowTime = DateTime.Now.Ticks;
            int  oldCnt  = sendPkgs.Count;
            int  sendLen = 0;

            foreach (var channel in channelArr.Values)
            {
                if (!channel.Empty())
                {
                    UdpPackage[] pkgs = pkgMatrix[channel.channelID];
                    for (long seqIdx = channel.firstSeqno; seqIdx < channel.lastSeqno; seqIdx++)
                    {
                        UdpPackage pkg = pkgs[SeqnoIdx(seqIdx)];
                        if (pkg.sendIndex == sendIndex)
                        {
                            continue;                             //当前发送队列已经标记发送
                        }
                        if (pkg != null && !pkg.isAckBack && pkg.sentCnt > 0)
                        {
                            long diffTime = pkg.sentTime + (peer.RoundTripTime + factor1) * 10000;
                            if (useResendDelayTimeArr)
                            {
                                diffTime += GetSendDelayTime(pkg.sentCnt);
                            }
                            if (diffTime < nowTime)
                            {
                                ////Log.Error("----------------------- TryTimeout: " + pkg.channelID + " SeqNo:" + pkg.seqNo + " DelayTime:" + ((nowTime - pkg.sentTime) / 10000));
                                pkg.sendIndex = sendIndex;
                                sendPkgs.Add(pkg);
                                sendLen += pkg.length;
                            }
                        }
                    }
                }
            }
            int moreCnt = sendPkgs.Count - oldCnt;

            if (moreCnt > 0)
            {
                ////Log.Error("----------------------- TryTimeout: " + moreCnt + " factor:" + factor1);
            }
            return(sendLen);
        }
Beispiel #6
0
        private void SetAllAckBack(int channelID, long seqNoRecved)
        {
            ChannelInfo channel = channelArr[channelID];

            if (channel.Empty())
            {
                return;                  //当前channel为空的
            }
            UdpPackage[] pkgs = pkgMatrix[channelID];
            for (long seqIdx = (maxSeqnoRecved - 1); seqIdx >= channel.firstSeqno; seqIdx--)
            {
                UdpPackage pkg = pkgs[SeqnoIdx(seqIdx)];
                if (pkg != null && !pkg.isAckBack)
                {
                    pkg.SetAckBacked(0);
                }
            }
            channel.firstSeqno = seqNoRecved;
        }
Beispiel #7
0
        protected int TryFlush()
        {
            int  sendLen = 0;
            long nowTime = DateTime.Now.Ticks;

            sendPkgs.Clear();
            couldApplyPkgs.Clear();
            foreach (var channel in channelArr.Values)
            {
                if (channel.Empty())
                {
                    continue;                  //当前channel为空的
                }
                UdpPackage[] pkgs = pkgMatrix[channel.channelID];
                for (long seqIdx = channel.firstSeqno; seqIdx < channel.lastSeqno; seqIdx++)
                {
                    UdpPackage pkg = pkgs[SeqnoIdx(seqIdx)];
                    if (pkg == null)
                    {
                        continue;
                    }
                    if (pkg.sendIndex == sendIndex)
                    {
                        continue;                             //当前发送队列已经标记发送
                    }
                    if (pkg.sentCnt > 0)
                    {
                        continue;
                    }
                    ////Log.Error("----------------------- TryFlush: " + pkg.channelID + " SeqNo:" + pkg.seqNo);
                    sendLen += pkg.length;
                    sendPkgs.Add(pkg);
                    pkg.sendIndex = sendIndex;
                }
            }
            //SendPkgs(sendPkgs, couldApplyPkgs);
            if (sendPkgs.Count > 0)
            {
                ////Log.Error("----------------------- TryFlush: " + sendPkgs.Count);
            }
            return(sendLen);
        }
Beispiel #8
0
 public void AddPkg(byte code, int _channelId, int _length, byte[] _pkg)
 {
     lock (threadLock)
     {
         if (!pkgMatrix.ContainsKey(_channelId))
         {
             pkgMatrix.Add(_channelId, new UdpPackage[maxPkgsPerChannel]);
             channelArr.Add(_channelId, new ChannelInfo(_channelId));
         }
         long newSeqNo = channelArr[_channelId].AllocSeqNo();
         if (channelArr[_channelId].Full())
         {// if packages cache pool is full
             ////Log.Error("UDP Driver: pkg pool is full...");
             peer.Disconnect();
             return;
         }
         ////Log.Error("====================AddPkg:" + code + " c: " + channelId + " Seqno:" + newSeqNo + " len:" + length + " fristS:" + channelArr[channelId].firstSeqno + " lastS:" + channelArr[channelId].lastSeqno);
         pkgMatrix[_channelId][SeqnoIdx(newSeqNo)] = new UdpPackage(code, _channelId, newSeqNo, _length, _pkg);
         //AlignSeqNo(newSeqNo, channelId);
     }
 }
Beispiel #9
0
        /*
         * 发送pkgs的接口
         * _sendPkgs:必须发送的pkg
         * _couldApplyPkgs: 为了补足mtu,可以附加发送的pkg
         */

        protected void SendPkgs()
        {
            int sentLen = 0;

            sendPkgsEx.Clear();
            for (int i = 0; i < sendPkgs.Count; i++)
            {
                UdpPackage pkg = sendPkgs[i];
                if (((sentLen + pkg.length) > maxBytesOnceSend && sendPkgsEx.Count > 0) || sendPkgsEx.Count > 50)
                {
                    SendPkgsEx(sendPkgsEx);
                    sentLen = 0;
                    sendPkgsEx.Clear();
                }
                sendPkgsEx.Add(pkg);
                sentLen += pkg.length;
            }
            if (sentLen > 0)
            {
                if (couldApplyPkgs != null)
                {
                    for (int i = 0; i < couldApplyPkgs.Count; i++)
                    {
                        UdpPackage pkg = couldApplyPkgs[i];
                        if (((sentLen + pkg.length) > maxBytesOnceSend && sendPkgsEx.Count > 0) || sendPkgsEx.Count > 50)
                        {
                            break; // 只有最后一个包需要补充到mtu大小
                        }
                        else
                        {
                            sendPkgsEx.Add(pkg);
                        }
                    }
                }
                SendPkgsEx(sendPkgsEx);
                sentLen = 0;
                sendPkgsEx.Clear();
            }
        }
Beispiel #10
0
        /*
         * 发送一些还没收到ACK,但是该channel新的pkg缺收到了ACK,所以基本可以断定此类pkg 丢掉了,需要重发
         */

        protected int TryResendLostPkg()
        {
            int sendLen = 0;
            int oldCnt  = sendPkgs.Count;

            foreach (var channel in channelArr.Values)
            {
                if (!channel.Empty())
                {
                    UdpPackage[] pkgs = pkgMatrix[channel.channelID];
                    for (long seqIdx = channel.firstSeqno; seqIdx < channel.lastSeqno; seqIdx++)
                    {
                        UdpPackage pkg = pkgs[SeqnoIdx(seqIdx)];
                        if (pkg.sendIndex == sendIndex)
                        {
                            continue;                             //当前发送队列已经标记发送
                        }
                        if (pkg != null && pkg.bLost)
                        {
                            //Log.Error("----------------------- TryLost: " + pkg.channelID + " SeqNo:" + pkg.seqNo);
                            pkg.sendIndex = sendIndex;
                            sendPkgs.Add(pkg);
                            sendLen += pkg.length;
                        }
                    }
                }
                //SendPkgs(sendPkgsEx, null);
            }
            int moreCnt = sendPkgs.Count - oldCnt;

            if (moreCnt > 0)
            {
                ////Log.Error("----------------------- TryLost: " + moreCnt);
            }
            return(sendLen);
        }
Beispiel #11
0
        protected int PrepairTimeoutPkg(int sendLen)
        {
            long nowTime = DateTime.Now.Ticks;

            foreach (var channel in channelArr.Values)
            {
                if (!channel.Empty())
                {
                    UdpPackage[] pkgs = pkgMatrix[channel.channelID];
                    for (long seqIdx = channel.firstSeqno; seqIdx < channel.lastSeqno; seqIdx++)
                    {
                        UdpPackage pkg = pkgs[SeqnoIdx(seqIdx)];
                        if (pkg.sendIndex == sendIndex)
                        {
                            continue;                             //当前发送队列已经标记发送
                        }
                        if (pkg != null && !pkg.isAckBack && pkg.sentCnt > 0)
                        {
                            long diffTime = (nowTime - (pkg.sentTime + peer.RoundTripTime * 10000)) / 10000;
                            if (diffTime < 0)
                            {
                                continue;
                            }
                            long idx = diffTime / maxTimeoutTimeDelay;
                            if (idx >= maxTimeoutArrLen)
                            {
                                idx = maxTimeoutArrLen - 1;
                            }

                            timeoutArr[idx].Add(pkg);

                            pkg.sendIndex = sendIndex;
                        }
                    }
                }
            }

            int  selfSendLen = 0;
            int  index       = (maxTimeoutArrLen - 1);
            bool bStop       = false;

            for (; index >= 2; index--)
            {
                List <UdpPackage> pkgList = timeoutArr[index];
                for (int n = 0; n < pkgList.Count; n++)
                {
                    UdpPackage pkg = pkgList[n];
                    if (bStop)
                    {
                        couldApplyPkgs.Add(pkg);
                    }
                    else
                    {
                        sendPkgs.Add(pkg);
                        ////Log.Error("----------------------- TryTimeout: " + pkg.channelID + " SeqNo:" + pkg.seqNo + " DelayTime:" + ((nowTime - pkg.sentTime) / 10000));
                        selfSendLen += pkg.length;
                    }
                    if ((selfSendLen + sendLen) > 1500)
                    {
                        bStop = true;
                    }
                }
                if (bStop)
                {
                    break;
                }
                if (index <= 4 && selfSendLen > 800)
                {//如果包只超时了一点点 4*37范围内,并且已经发送了超过800byte 就不要再多发了
                    break;
                }
                if (selfSendLen > 1200)
                {
                    break;
                }
            }
            for (; index >= 0; index--)
            {
                List <UdpPackage> pkgList = timeoutArr[index];
                for (int n = 0; n < pkgList.Count; n++)
                {
                    UdpPackage pkg = pkgList[n];
                    couldApplyPkgs.Add(pkg);
                    ////Log.Error("----------------------- TryCouldApply: " + pkg.channelID + " SeqNo:" + pkg.seqNo + " DelayTime:" + ((nowTime - pkg.sentTime) / 10000));
                }
            }
            return(selfSendLen);
        }