private void CreateDownload(TransferParameter parameter) { try { bool allowRanges = false; int contentLength; _request = DownloadRequst.GetWebRequest(parameter); _request.PreAuthenticate = true; _request.Accept = "*/*"; _request.AllowAutoRedirect = true; _request.Method = "HEAD"; Log.Debug("^ GET {0} HTTP/{1}", parameter.TransferUrl, _request.ProtocolVersion); Log.Debug("^ Host: {0}", _request.Address.Host); Log.Debug("^ Accept: {0}", _request.Accept); Log.Debug("^ User-Agent: {0}", _request.UserAgent); Log.Debug("^ Referer: {0}", _request.Referer); var response = (HttpWebResponse)_request.GetResponse(); if (response.ContentLength == -1 || response.ContentLength > 0x7fffffff) { contentLength = 1024 * 1024 * 5; } else { contentLength = (int)response.ContentLength; } Log.Debug("v HTTP/{0} {1} OK", response.ProtocolVersion, response.StatusCode); for (int i = 0; i < response.Headers.Count; ++i) { if (String.Compare(response.Headers.Keys[i], "Accept-Ranges", StringComparison.InvariantCultureIgnoreCase) == 0) { allowRanges = true; } Log.Debug("v {0}: {1}", response.Headers.Keys[i], response.Headers[i]); } response.Close(); lock (this) { FileUtil.CreateFile(parameter.LocalFile, contentLength); } DownloadFileState = new FileState(parameter.TransferUrl, parameter.LocalFile, contentLength, (allowRanges ? _chunkCount : (short)1)); AssignFileStateDelegate(); DownloadFileState.FireFileDownloadBeginingEvent(); } catch (WebException e) { Log.Warn("- Got an Excetpion {0} in Create WebException", e.ToString()); if (e.Status == WebExceptionStatus.ProtocolError) { string a = ((HttpWebResponse)e.Response).StatusCode.ToString(); a += ((HttpWebResponse)e.Response).StatusDescription; Log.Warn(a); } throw new WebException(e.Message); } catch (Exception e) { Log.Warn("- Got an Excetpion {0} in Create Exception", e.ToString()); throw new Exception(e.Message); } }
public ThreadParameters(FileState state, short blockIndex, ThreadProcDelegate threaddelegate) { _fileState = state; _blockIndex = blockIndex; _threaddelegate = threaddelegate; }
private long DownloadChunkBlock(FileState state, short blockIndex) { Stream rsm = null; HttpWebResponse response = null; HttpWebRequest request = null; int errorCount = 0; retry: try { BlockState bs = state.GetBlock(blockIndex); if (bs == null || bs.Size <= 0) { return(-1); } Log.Debug("- DownloadChunkBlock index:{0}[{1}-{2}]", blockIndex, bs.EnterPoint, bs.UnTransmittedSize); if (bs.IsCompleted) { return(0); } using (var fs = File.Open(state.LocalFileUri.LocalPath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite)) { Log.Debug("- Open file {0} successful!", state.LocalFileUri.LocalPath); fs.Seek(bs.EnterPoint, SeekOrigin.Begin); Log.Debug("- File seek({0}) successful!", bs.EnterPoint); int count = bs.UnTransmittedSize; request = DownloadRequst.GetWebRequest(state.RemoteFileUri, Parameter.Environment); request.Accept = "*/*"; request.AllowAutoRedirect = true; request.ProtocolVersion = HttpVersion.Version10; request.Timeout = Timeout.Infinite; //request.CookieContainer = CookieUtil.GetCokieContainer(state.RemoteFileInfo); if (state.BlockCount > 1) { request.AddRange(bs.EnterPoint); } for (int i = 0; i < request.Headers.Count; ++i) { Log.Debug("^ [{2}]{0}: {1}", request.Headers.Keys[i], request.Headers[i], blockIndex); } Log.Debug("- [{0}]请求开始", blockIndex); response = (HttpWebResponse)request.GetResponse(); Log.Debug("- [{0}]请求返回", blockIndex); const int buffersize = 64 * 1024; var buffer = new byte[buffersize]; rsm = response.GetResponseStream(); Log.Debug("- [{0}]开始接收数据!", blockIndex); bs.BlockRunState = ActionStateType.Running; while (count > 0) { if (bs.AssistThread == null) { Log.Debug("- AssistThread is null"); } if (bs.BlockRunState == ActionStateType.Stop) { Log.Info("- [{0}] Stoped,Address:{1}", blockIndex, bs.EnterPoint); break; } int ret = (rsm != null ? rsm.Read(buffer, 0, buffersize) : 0); if (ret <= 0) { Log.Debug("- Receive Data Error, 5 seconds retry!"); Thread.Sleep(5000); continue; } int retcopy = (count < ret ? count : ret); fs.Write(buffer, 0, retcopy); count -= retcopy; bs.TransmittedSize += retcopy; state.TransmittedLength += retcopy; if (count <= 0) { break; } } fs.Close(); } Log.Debug("- [{0}]数据接收完成!", blockIndex); } catch (WebException e) { Log.Info(e.ToString()); Log.Warn(e.Status.ToString()); if (e.Status == WebExceptionStatus.ProtocolError) { // state.SaveLogFile(); return(-1); } if (e.Status == WebExceptionStatus.ReceiveFailure) { errorCount++; if (errorCount <= 3) { Thread.Sleep(1000); Log.Info("goto retry {0} times by ReceiveFailure", errorCount); goto retry; } } if (e.Status == WebExceptionStatus.Timeout) { errorCount++; if (errorCount <= 5) { Thread.Sleep(1000); Log.Info("goto retry {0} times by Timeout: {1}", errorCount, e.InnerException.Message); goto retry; } } Log.Error(e); } catch (ThreadAbortException e) { Log.Warn(e.ToString()); } catch (Exception e) { Log.Info(e.ToString()); // state.SaveLogFile(); return(-1); } finally { if (rsm != null) { rsm.Close(); } if (response != null) { response.Close(); } if (request != null) { request.Abort(); } Log.Info("{0} block is finished!", blockIndex); // state.SaveLogFile(); } return(0); }
private long DownloadChunkBlock(FileState state, short blockIndex) { try { string strResult; int code; BlockState bs = state.GetBlock(blockIndex); if (bs == null || bs.Size <= 0) { return(-1); } Socket s = Login(); if (s == null) { return(-1); } Log.Debug("- DownloadChunkBlock index:{0}[{1}-{2}]", blockIndex, bs.EnterPoint, bs.UnTransmittedSize); if (bs.IsCompleted) { return(0); } int count = bs.UnTransmittedSize; Log.Debug("- [{0}]开始接收数据!", blockIndex); Socket dataSocket = CreateDataSocket(s); if (dataSocket == null) { Log.Debug("- Create Data socket faild!"); return(-1); } SetMode(s, true); if (state.BlockCount > 1 && bs.EnterPoint > 0) { strResult = SendFtpCommand(s, "REST " + bs.EnterPoint); if (GetResultCode(strResult) != 350) { Log.Debug("- server may not support resuming. thread exit!"); CleanUp(dataSocket, false); CleanUp(s, true); return(0); } } strResult = SendFtpCommand(s, "RETR " + GetUnescapeString(_transferUri.AbsolutePath)); code = GetResultCode(strResult); if (!(code == 150 || code == 125 || code == 226)) { Log.Debug(strResult.Substring(4)); CleanUp(dataSocket, false); CleanUp(s, true); return(0); } using (var fs = File.Open(state.LocalFileUri.LocalPath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite)) { Log.Debug("- Open file {0} successful!", state.LocalFileUri.LocalPath); fs.Seek(bs.EnterPoint, SeekOrigin.Begin); Log.Debug("- File seek({0}) successful!", bs.EnterPoint); int buffersize = /*((Environment!=null) ? Environment.WritetoDiskBufferSize :*/ 64 * 1024; var buffer = new byte[buffersize]; bs.BlockRunState = ActionStateType.Running; while (count > 0) { if (bs.AssistThread == null) { Log.Debug("- AssistThread is null"); } if (bs.BlockRunState == ActionStateType.Pause && bs.AssistThread != null && bs.AssistThread.IsAlive) { Log.Debug("- [{0}] Paused,Address:{1}", blockIndex, bs.EnterPoint); bs.AssistThread.Suspend(); } if (bs.BlockRunState == ActionStateType.Stop) { break; } int ret = dataSocket.Receive(buffer, buffersize, 0); bool error = false; if (ret <= 0) { Log.Debug("- Receive Data Error, 5 seconds retry!"); Thread.Sleep(5000); continue; } try { int retcopy = (count < ret ? count : ret); fs.Write(buffer, 0, retcopy); count -= retcopy; bs.TransmittedSize += retcopy; state.TransmittedLength += retcopy; } catch (Exception e) { Log.Debug(e.ToString()); error = true; } finally { if (error) { fs.Close(); } } if (error || count <= 0) { break; } } CleanUp(dataSocket, false); CleanUp(s, true); state.CanFireDownloadCompletedEvent(); fs.Close(); } } catch (Exception e) { Log.Debug(e); return(-1); } return(0); }