C# FtpWebRequest.Timeout不工作和FtpWebRequest.GetResponse阻塞

C# FtpWebRequest.Timeout不工作和FtpWebRequest.GetResponse阻塞,c#,ftp,ftpwebrequest,C#,Ftp,Ftpwebrequest,我经常上传一个大文件, 然后,在50毫秒的网络延迟和50%的丢包率下,我在FtpWebRequest.GetRequestStream.Write上收到一个IOException,这会使网络变得更糟 我调用FtpWebRequest.GetResponse.Close并希望重新上载该文件,但被阻止 ftp服务器是filezilla 0.9.53,.net版本是2.0。 我的代码显示如下,最后我为我糟糕的英语感到抱歉 public class FtpUploader { public Ft

我经常上传一个大文件, 然后,在50毫秒的网络延迟和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;
}
公共类FtpUploader
{
公共FtpUploader(字符串用户名、字符串密码)
{
this.certificate=新的网络凭据(用户名、密码);
}
public void上传文件(字符串srcFile,Uri desUri)
{
int retry=20,iLoop=0;
bool finished=UploadFile(srcFile、desUri、WebRequestMethods.Ftp.UploadFile);
当(!完成)
{
如果(iLoop++>=重试)
{
抛出新异常(string.Format(“上载失败”,srcFile,重试));
}
finished=UploadFile(srcFile、desUri、WebRequestMethods.Ftp.AppendFile);
}
}
私有FtpWebRequest CreateFtpWebRequest(Uri,字符串方法)
{
FtpWebRequest ftpClientRequest=(FtpWebRequest)FtpWebRequest.Create(uri);
ftpClientRequest.Credentials=证书;
ftpClientRequest.KeepAlive=false;
ftpClientRequest.Method=Method;
ftpClientRequest.Timeout=20*1000;
ftpClientRequest.ReadWriteTimeout=5*1000;
返回ftpClientRequest;
}
私有长GetFileSize(Uri)
{
FtpWebRequest ftpClientRequest=CreateFtpWebRequest(uri,WebRequestMethods.Ftp.GetFileSize);
FtpWebResponse响应=(FtpWebResponse)ftpClientRequest.GetResponse();
long size=response.ContentLength;
response.Close();
返回大小;
}
私有bool上传文件(字符串srcFile、Uri desUri、字符串ftpMethod)
{
尝试
{
长偏移=0;
if(ftpMethod==WebRequestMethods.Ftp.AppendFile)
{
offset=GetFileSize(desUri);
}
FtpWebRequest请求=CreateFtpWebRequest(desUri,ftpMethod);
request.ContentOffset=偏移量;
Stream desStream=request.GetRequestStream();
FileStream srcStream=newfilestream(srcFile,FileMode.Open,FileAccess.Read);
尝试
{
WriteToDestination(srcStream、desStream、offset);
}
catch(异常ioEx)//IOException
{
LogErrorMsg(ioEx.Message);
}
WebResponse=request.GetResponse();//阻塞
response.Close();
}
捕获(例外情况除外)
{
LogErrorMsg(例如消息);
返回false;
}
返回true;
}
私有void WriteToDestination(流srcStream、流desStream、长偏移量)
{
srcStream.Seek(offset,SeekOrigin.Begin);
int bufSize=4096;
字节[]缓冲区=新字节[bufSize];
long srcLength=srcStream.Length;
while(偏移量
我不知道为什么GetResponse会在Timeout属性无效时阻塞,但我最终发现我可以使用FtpWebRequest.Abort来尝试释放连接。