void CloseSocket(DownChunkData chunk) { try { chunk.Fcd.socket.Close(); } catch { } chunk.Fcd = null; }
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; }
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); }
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); }
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); } }
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; }
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); }
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); }