Exemplo n.º 1
0
 //按照服务器的失败次数、使用情况、成功次数排序。
 static int SortCheckServer(CheckServerIP a, CheckServerIP b)
 {
     if (a.FailedCount + 3 < b.FailedCount)
     {
         return(-1);
     }
     else if (a.FailedCount > b.FailedCount + 3)
     {
         return(1);
     }
     else if (a.UseCount < b.UseCount)
     {
         return(-1);
     }
     else if (a.UseCount > b.UseCount)
     {
         return(1);
     }
     else if (a.OkCount > b.OkCount)
     {
         return(-1);
     }
     else if (a.OkCount < b.OkCount)
     {
         return(1);
     }
     else
     {
         return(0);
     }
 }
Exemplo n.º 2
0
    bool DownMultiFiles(DownloadData dd)
    {
        MultiFileDownData    mfdd       = (MultiFileDownData)dd.Data;
        List <DownChunkData> chunkList  = new List <DownChunkData>();
        List <DownChunkData> waitList   = new List <DownChunkData>();
        List <DownChunkData> retryList  = new List <DownChunkData>();
        List <CheckServerIP> serverList = new List <CheckServerIP>();
        bool bHasNoYD = false;

        for (byte i = 0; i < mfdd.FTPIPList.Count; ++i)
        {
            CheckServerIP ssi = new CheckServerIP(i);
            if (mfdd.FTPIPList[i].ISP == (byte)ISPType.ISP_YD)
            {
                ssi.FailedCount = (uint)(MAX_CHUNK_COUNT * 2);
            }
            serverList.Add(ssi);
            if (mfdd.FTPIPList[i].ISP != (byte)ISPType.ISP_YD)
            {
                bHasNoYD = true;
            }
        }
        //1.划分Chunk
        //================================
        uint tick        = Utility.GetTickCount();
        byte ipidx       = 0;
        int  CHUNK_SIZE2 = CHUNK_SIZE << 1;
        uint chunkIdx    = 0;

        for (byte i = 0; i < mfdd.FileList.Count; ++i)
        {
            int resSize   = (int)mfdd.FileList[i].ResSize;
            int resOffset = 0;
            while (resSize > 0)
            {
                DownChunkData dcd = new DownChunkData();
                dcd.FileIdx = i;
                if (resSize >= CHUNK_SIZE2)
                {
                    dcd.Length = CHUNK_SIZE;
                }
                else
                {
                    dcd.Length = resSize;
                }
                dcd.ChunkIdx = chunkIdx++;
                dcd.Offset   = resOffset;
                dcd.RecvSize = 0;
                dcd.RecvTick = 0;
                resOffset   += dcd.Length;
                resSize     -= dcd.Length;
                if (chunkList.Count < MAX_CHUNK_COUNT)
                {
                    do
                    {
                        ipidx = (byte)((ipidx + 1) % serverList.Count);
                    } while (bHasNoYD && mfdd.FTPIPList[ipidx].ISP == (byte)ISPType.ISP_YD);
                    dcd.checkServer = serverList[ipidx];
                    dcd.checkServer.BeginUse();
                    if (!InitChunk(dd, dcd, mfdd.FTPIPList[ipidx]))
                    {
                        return(false);
                    }
                    dcd.RecvTick = tick;
                    chunkList.Add(dcd);
                }
                else
                {
                    waitList.Add(dcd);
                }
            }
        }
        //1.接收Chunk
        //================================
        while (true)
        {
            tick = Utility.GetTickCount();
            for (int i = 0; i < chunkList.Count;)
            {
                DownChunkData chunk = chunkList[i];
                if (!DownChunk(dd, chunk, tick))
                {
                    CloseSocket(chunk);
                    chunk.checkServer.EndUse(chunk.State != ChunkState.CHUNK_CONNECT && chunk.RecvSize != 0);
                    if (chunk.State == ChunkState.CHUNK_RECV_DATA)
                    {
                        //将接收的数据coy到data
                        CopyBuffToData(mfdd, chunk);
                        chunk.Offset  += chunk.RecvSize;
                        chunk.Length  -= chunk.RecvSize;
                        chunk.RecvSize = 0;
                        ++chunk.RetryCount;
                        chunk.SendCmdData = null;
                    }
                    if (chunk.RetryCount >= MAX_RETRY_COUNT)
                    {
                        //split
                        if ((chunk.Length > MAX_XOR_SIZE || chunk.XOR == 1) && chunk.Length > 16)
                        {
                            DownChunkData dcd1, dcd2;
                            SplitChunk(ref chunkIdx, chunk, out dcd1, out dcd2);
                            waitList.Add(dcd1);
                            waitList.Add(dcd2);
                        }
                        else
                        {
                            chunk.RetryCount  = 0;
                            chunk.XOR         = 1;
                            chunk.SendCmdData = null;
                            retryList.Add(chunk);
                        }
                    }
                    else
                    {
                        retryList.Add(chunk);
                    }
                    Utility.ListRemoveAt(chunkList, i);
                    continue;
                }
                else if (chunk.State == ChunkState.CHUNK_COMPLETION)
                {
                    CopyBuffToData(mfdd, chunk);
                    CloseSocket(chunk);
                    chunk.checkServer.EndUse(true);
                    RecvFileDataFlag cfd = mfdd.RecvFileList[chunk.FileIdx];
                    if (cfd.RecvSize == cfd.FileData.Length)
                    {
                        //完成
                        MultiFileOK mfo = new MultiFileOK();
                        mfo.Data = cfd.FileData;
                        mfo.Drd  = mfdd.FileList[chunk.FileIdx];
                        mfdd.CompletionList[mfdd.RecvCount] = mfo;
                        if (++mfdd.RecvCount == mfdd.FileList.Count)
                        {
                            Debug.Log("所有文件完成!");
                            return(true);
                        }
                    }
                    Utility.ListRemoveAt(chunkList, i);
                    continue;
                }
                ++i;
            }//end for

            if (chunkList.Count < MAX_CHUNK_COUNT)
            {
                tick = Utility.GetTickCount();
                DownChunkData dcd = null;
                if (waitList.Count > 0)
                {
                    dcd = waitList[0];
                    waitList.RemoveAt(0);
                }
                else if (retryList.Count > 0)
                {
                    dcd = retryList[0];
                    retryList.RemoveAt(0);
                }
                if (dcd != null)
                {
                    serverList.Sort(SortCheckServer);
                    serverList[0].BeginUse();
                    dcd.checkServer = serverList[0];
                    if (!InitChunk(dd, dcd, mfdd.FTPIPList[dcd.checkServer.ServerIdx]))
                    {
                        return(false);
                    }
                    dcd.RecvTick = Utility.GetTickCount();
                    chunkList.Add(dcd);
                }
            }
            if (mfdd.RecvCount == mfdd.FileList.Count)
            {
                break;
            }
            Thread.Sleep(1);
        }
        ; //end while
        return(true);
    }