FtpWebRequest.Timeout无效,FtpWebRequest.GetResponse阻塞

时间:2015-07-06 05:53:12

标签: c# ftp ftpwebrequest

我使用FtpWebRequest上传大文件, 然后使用Clumsy使网络在50ms网络滞后和50%丢包率下变得更糟,我在FtpWebRequest.GetRequestStream.Write上收到了IOException。

我调用FtpWebRequest.GetResponse.Close并希望重新上传文件,但它会阻止。

ftp服务器是filezilla 0.9.53,.net版本是2.0。 我的代码显示如下,最后我为我糟糕的英语感到抱歉。

public class FtpUploader
{
    public FtpUploader(string username, string password)
    {
        this.certificate = new NetworkCredential(username, password);
    }

    public void UploadFile(string srcFile, Uri desUri)
    {
        int retry = 20, iLoop = 0;
        bool finished = UploadFile(srcFile, desUri, WebRequestMethods.Ftp.UploadFile);
        while (!finished)
        {
            if (iLoop++ >= retry)
            {
                throw new Exception(string.Format("Upload Fail", srcFile, retry));
            }
            finished = UploadFile(srcFile, desUri, WebRequestMethods.Ftp.AppendFile);
        }
    }

    private FtpWebRequest CreateFtpWebRequest(Uri uri, string method)
    {
        FtpWebRequest ftpClientRequest = (FtpWebRequest)FtpWebRequest.Create(uri);
        ftpClientRequest.Credentials = certificate;
        ftpClientRequest.KeepAlive = false;
        ftpClientRequest.Method = method;
        ftpClientRequest.Timeout = 20 * 1000;
        ftpClientRequest.ReadWriteTimeout = 5 * 1000;
        return ftpClientRequest;
    }

    private long GetFileSize(Uri uri)
    {
        FtpWebRequest ftpClientRequest = CreateFtpWebRequest(uri, WebRequestMethods.Ftp.GetFileSize);
        FtpWebResponse response = (FtpWebResponse)ftpClientRequest.GetResponse();
        long size = response.ContentLength;
        response.Close();
        return size;
    }

    private bool UploadFile(string srcFile, Uri desUri, string ftpMethod)
    {
        try
        {
            long offset = 0;
            if (ftpMethod == WebRequestMethods.Ftp.AppendFile)
            {
                offset = GetFileSize(desUri);
            }

            FtpWebRequest request = CreateFtpWebRequest(desUri, ftpMethod);
            request.ContentOffset = offset;
            Stream desStream = request.GetRequestStream();
            FileStream srcStream = new FileStream(srcFile, FileMode.Open, FileAccess.Read);

            try
            {
                WriteToDestination(srcStream, desStream, offset);
            }
            catch (Exception ioEx) // IOException
            {
                LogErrorMsg(ioEx.Message);
            }

            WebResponse response = request.GetResponse(); // blocking
            response.Close();
        }
        catch (Exception ex)
        {
            LogErrorMsg(ex.Message);
            return false;
        }
        return true;
    }

    private void WriteToDestination(Stream srcStream, Stream desStream, long offset)
    {
        srcStream.Seek(offset, SeekOrigin.Begin);
        int bufSize = 4096;
        byte[] buffer = new byte[bufSize];
        long srcLength = srcStream.Length;

        while (offset < srcLength)
        {
            int bytesRead = srcStream.Read(buffer, 0, bufSize);
            desStream.Write(buffer, 0, bytesRead);
            offset += bytesRead;
        }
    }

    private void LogErrorMsg(string msg)
    {
    }

    private NetworkCredential certificate;
}

0 个答案:

没有答案