Exemple #1
0
 void CloseSocket(DownChunkData chunk)
 {
     try
     {
         chunk.Fcd.socket.Close();
     }
     catch
     {
     }
     chunk.Fcd = null;
 }
Exemple #2
0
    void CopyBuffToData(MultiFileDownData mfdd, DownChunkData chunk)
    {
        RecvFileDataFlag cfd = mfdd.RecvFileList[chunk.FileIdx];

        if (cfd.FileData == null)
        {
            cfd.FileData = new byte[mfdd.FileList[chunk.FileIdx].ResSize];
        }
        System.Array.Copy(chunk.RecvData, 0, cfd.FileData, chunk.Offset, chunk.RecvSize);
        cfd.RecvSize += (uint)chunk.RecvSize;
    }
Exemple #3
0
    bool CreateChunkCmdData(DownloadData dd, DownChunkData dcd)
    {
        MultiFileDownData mfdd   = (MultiFileDownData)dd.Data;
        DownResData       curDrd = mfdd.FileList[dcd.FileIdx];

        try
        {
            //1.封装命令
            if (dd.Type == DownloadType.DOWNLOAD_CHECK_VER)
            {
                NetCmdCheckVer cmd = new NetCmdCheckVer();
                cmd.SetCmdType(NetCmdType.CMD_EXTRA_CHECK_VER);
                cmd.Version      = ServerSetting.ClientVer;
                cmd.Plateform    = (byte)RuntimeInfo.GetPlatform();
                cmd.ScreenWidth  = (ushort)Resolution.GetScreenWidth();
                cmd.ScreenHeight = (ushort)Resolution.GetScreenHeight();
                cmd.FileName     = System.Text.Encoding.ASCII.GetBytes(curDrd.ResUrl);
                cmd.Length       = (ushort)mfdd.FileList[0].ResUrl.Length;
                SetPcakgeMac(cmd, m_PackageName, m_MacAddress);
                dcd.SendCmdData = NetCmdHelper.CmdToBytes <NetCmdCheckVer>(cmd, 0);
            }
            else
            {
                byte[] data1    = System.BitConverter.GetBytes(dcd.Offset);
                byte[] data2    = System.BitConverter.GetBytes(dcd.Length);
                byte[] dataUrl  = System.Text.Encoding.ASCII.GetBytes(curDrd.ResUrl);
                byte[] sendData = new byte[data1.Length + data2.Length + dataUrl.Length + 1];
                System.Array.Copy(data1, 0, sendData, 0, 4);
                System.Array.Copy(data2, 0, sendData, 4, 4);
                System.Array.Copy(dataUrl, 0, sendData, 8, dataUrl.Length);

                NetCmdFileRequest ncf = new NetCmdFileRequest();
                ncf.FileName = sendData;
                ncf.Count    = (ushort)(mfdd.FileList.Count | ((int)dcd.XOR << 15)); //高位是1表示要异或
                ncf.Length   = (ushort)sendData.Length;
                ncf.SetCmdType(NetCmdType.CMD_EXTRA_FILE_EX);
                dcd.SendCmdData = NetCmdHelper.CmdToBytes <NetCmdFileRequest>(ncf, 0);
            }
        }
        catch (System.Exception e)
        {
            throw new System.Exception("CreateChunkCmdData Err:" + e.ToString());
            return(false);
        }
        return(true);
    }
Exemple #4
0
 bool InitChunk(DownloadData dd, DownChunkData dcd, ServerIPData sid)
 {
     if (dcd.SendCmdData == null)
     {
         if (!CreateChunkCmdData(dd, dcd))
         {
             Debug.Log("创建FTP命令失败1!");
             return(false);
         }
     }
     dcd.Fcd   = CreateConnectData(sid);
     dcd.State = ChunkState.CHUNK_CONNECT;
     if (dcd.RecvData == null || dcd.RecvData.Length < dcd.Length)
     {
         dcd.RecvData = new byte[dcd.Length];
     }
     return(true);
 }
Exemple #5
0
    bool DownSingleFiles(DownloadData dd)
    {
        MultiFileDownData mfdd  = (MultiFileDownData)dd.Data;
        DownChunkData     chunk = new DownChunkData();

        chunk.FileIdx  = 0;
        chunk.Length   = 0;
        chunk.Offset   = 0;
        chunk.RecvSize = 0;
        chunk.RecvData = new byte[128];
        chunk.State    = ChunkState.CHUNK_CONNECT;
        if (!InitChunk(dd, chunk, mfdd.FTPIPList[0]))
        {
            return(false);
        }
        chunk.RecvTick = Utility.GetTickCount();
        while (true)
        {
            uint tick = Utility.GetTickCount();
            if (!DownChunk(dd, chunk, tick))
            {
                dd.Data = mfdd.ExtraData;
                CloseSocket(chunk);
                return(false);
            }
            else if (chunk.State == ChunkState.CHUNK_COMPLETION)
            {
                dd.Data = mfdd.ExtraData;
                CloseSocket(chunk);
                if (chunk.RecvData.Length != chunk.Length)
                {
                    dd.m_Bytes = new byte[chunk.Length];
                    System.Array.Copy(chunk.RecvData, dd.m_Bytes, chunk.Length);
                }
                else
                {
                    dd.m_Bytes = chunk.RecvData;
                }
                return(true);
            }
            Thread.Sleep(1);
        }
    }
Exemple #6
0
    void SplitChunk(ref uint idx, DownChunkData drd, out DownChunkData dcd1, out DownChunkData dcd2)
    {
        int halfSize = drd.Length / 2;

        dcd1            = new DownChunkData();
        dcd2            = new DownChunkData();
        dcd1.Offset     = drd.Offset;
        dcd1.RecvSize   = 0;
        dcd1.RecvTick   = 0;
        dcd1.Length     = halfSize;
        dcd1.ChunkIdx   = idx++;
        dcd1.RetryCount = drd.RetryCount;
        dcd1.XOR        = drd.XOR;
        dcd1.FileIdx    = drd.FileIdx;

        dcd2.Offset     = dcd1.Offset + dcd1.Length;
        dcd2.RecvSize   = 0;
        dcd2.RecvTick   = 0;
        dcd2.Length     = halfSize;
        dcd2.ChunkIdx   = idx++;
        dcd2.RetryCount = drd.RetryCount;
        dcd1.XOR        = drd.XOR;
        dcd2.FileIdx    = drd.FileIdx;
    }
Exemple #7
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);
    }
Exemple #8
0
    bool DownChunk(DownloadData dd, DownChunkData dcd, uint tick)
    {
        int ret = 0;

        switch (dcd.State)
        {
        case ChunkState.CHUNK_CONNECT:
            if (dcd.Fcd.connected)
            {
                dcd.Fcd.socket.Blocking = false;
                dcd.State    = ChunkState.CHUNK_SEND_CMD;
                dcd.RecvTick = tick;
                return(true);
            }
            return(tick - dcd.RecvTick < 3000);

            break;

        case ChunkState.CHUNK_SEND_CMD:
            try
            {
                ret = dcd.Fcd.socket.Send(dcd.SendCmdData, SocketFlags.None);
                if (ret == dcd.SendCmdData.Length)
                {
                    dcd.State       = ChunkState.CHUNK_RECV_SIZE;
                    dcd.SendCmdData = null;
                    dcd.RecvTick    = tick;

                    return(true);
                }
            }
            catch
            {
                if (dcd.Fcd.socket.Connected == false)
                {
                    return(false);
                }
            }
            return(tick - dcd.RecvTick < TIME_OUT);

            break;

        case ChunkState.CHUNK_RECV_SIZE:
            try
            {
                ret = dcd.Fcd.socket.Receive(dcd.RecvData, dcd.RecvSize, dcd.RecvData.Length - dcd.RecvSize, SocketFlags.None);
            }
            catch
            {
                if (dcd.Fcd.socket.Connected == false)
                {
                    return(false);
                }
            }
            if (ret <= 0)
            {
                return(tick - dcd.RecvTick < TIME_OUT);
            }
            dcd.RecvTick  = tick;
            dcd.RecvSize += ret;
            int retIdx = 0;
            while (dcd.RecvSize >= 4)
            {
                uint recvID = System.BitConverter.ToUInt32(dcd.RecvData, retIdx);
                retIdx       += 4;
                dcd.RecvSize -= 4;
                if (recvID == 0xEFFFFFFF)
                {
                    //正在等待打开文件中
                }
                else if ((recvID & 0xF0000000) == 0xF0000000)
                {
                    //文件大小
                    recvID &= 0x0fffffff;
                    if (dcd.Length == 0)
                    {
                        dcd.Length = (int)recvID;
                    }
                    else if (dcd.Length != recvID)
                    {
                        throw new System.Exception("Recv FileSize Error:ServerSize:" + recvID + ", LocalSize:" + dcd.Length);
                        return(false);
                    }
                    if (dcd.RecvData.Length < dcd.Length)
                    {
                        byte[] recvdata = new byte[dcd.Length];
                        CopyXorData(dcd.RecvData, retIdx, recvdata, dcd.RecvSize, dcd.XOR == 1);
                        retIdx       = 0;
                        dcd.RecvData = recvdata;
                    }
                    //接收完成
                    dd.Queue          = 0xffffffff;
                    dcd.State         = ChunkState.CHUNK_RECV_DATA;
                    dcd.RecvTick      = tick;
                    dd.DownloadBytes += (uint)dcd.RecvSize;
                    break;
                }
                else if ((recvID & 0xC0000000) == 0xC0000000)
                {
                    //文件个数
                    byte isp = (byte)((recvID >> 28) & 0x3);
                    if (dd.Type == DownloadType.DOWNLOAD_CHECK_VER)
                    {
                        ISP_TYPE = isp;
                        // LogMgr.Log("<ISP:" + ((ISPType)ISP_TYPE) + ">");
                    }
                    recvID &= 0xff;
                    if (recvID != 1)
                    {
                        throw new System.Exception("File Count Error,ServerCount:" + recvID + ", LocalCount:1");
                        return(false);
                    }
                }
                else if ((recvID & 0x80000000) != 0)
                {
                    //排队中
                    dd.Queue = (recvID) & 0x7fffffff;
                }
                else
                {
                    throw new System.Exception("未知的RecvSize数据:" + recvID);
                    return(false);
                }
            }
            //移动数据到最开始
            if (retIdx != 0)
            {
                CopyXorData(dcd.RecvData, retIdx, dcd.RecvData, dcd.RecvSize, (dcd.XOR == 1 && dcd.State == ChunkState.CHUNK_RECV_DATA));
            }
            if (dcd.State == ChunkState.CHUNK_RECV_DATA && dcd.RecvSize == dcd.Length)
            {
                dcd.State = ChunkState.CHUNK_COMPLETION;
            }
            return(true);

            break;

        case ChunkState.CHUNK_RECV_DATA:
            try
            {
                ret = dcd.Fcd.socket.Receive(dcd.RecvData, dcd.RecvSize, dcd.Length - dcd.RecvSize, SocketFlags.None);
            }
            catch (SocketException e)
            {
                if (dcd.Fcd.socket.Connected == false)
                {
                    return(false);
                }
            }
            if (ret <= 0)
            {
                if (tick - dcd.RecvTick < TIME_OUT)
                {
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
            if (dcd.XOR == 1)
            {
                int endsize = dcd.RecvSize + ret;
                for (int i = dcd.RecvSize; i < endsize; ++i)
                {
                    dcd.RecvData[i] ^= XOR_MASK;
                }
            }
            dcd.RecvTick      = tick;
            dcd.RecvSize     += ret;
            dd.DownloadBytes += (uint)ret;
            if (dcd.RecvSize == dcd.Length)
            {
                dcd.State = ChunkState.CHUNK_COMPLETION;
            }
            return(true);

        default:
            throw new System.Exception("未知的Recv状态:" + dcd.State);
            return(false);
        }
        return(false);
    }