none
Background Transfer upload的网络问题 RRS feed

  • 问题

  • Hi:

       我在 http://code.msdn.microsoft.com/windowsapps/Background-Transfer-Sample-d7833f61 里面试用,第一个是uploader app, 第二个是downloader app. 我在调用下载文件的过程中去断开网络,当网络连上之后,download会自动的进行重新从0开始下载;但是,upload的过程在断网、连网之后会不能继续进行了。我发现两者在处理Handle**loadAsync 的过程是不一样的,下载在处理网络断开的时候会在DownloadProgress里面会去判断当前的download.Progress.Status状态,进入PausedNoNetwork,当网络连接后,会有if(download.Progress.HasRestarted){}去判断时候开始;但是Upload在处理HandleUploadAsync时,一旦网络断开,就会跳出UploadProgress()过程,报出Exception 错误,以致达不到连网后重新开始上传的效果。

       我是新手,有谁可以帮帮我吗?

        谢谢!

    2012年8月6日 2:22

答案

  • 不管下载也好,上传也好,请求主体都是你的客户端,并非服务端。 所以这里就有一个问题,如果是下载的话,我客户端下载了多少,还需要多少,从哪里断开并且连接上,这些信息都是客户端知道的。所以在处理下载断线问题时候,如果服务器支持了断点功能,则是可以断点续传的。  但是上传就不一样了,你请求上传数据到服务端,服务端同意并且它是盲目的接受数据,他并不会实时告诉客户端我接受到哪里了,我还有多少没有接受,我目前需要什么数据,因为所有数据都在客户端,服务端是猜测不了下一步所要的动作和数据的。 如果这个时候,网络断线,则服务端他没有必要帮助客户端维持一个会话,等待你的续传。而客户端也难以控制服务端是否可以接受数据,所有这一切在断线后就需要重新请求和传输。由于主体式客户端,则我们就需要客户端在上传时候进行大量的控制,并且主动提供数据,服务端他是被动接受,所以在此情况下,我们通常都是抛出异常重新进行连接传输。以防传输数据在服务端产生错误。

    你应该要做的是,在你的应用中处理此异常,然后重新请求进行上传。

    ---------------------

    不过也并不是没有断点上传,但是通常我们都需要服务端进行记录上传的数据和维持会话,这样在重新请求后,我们可以先检查服务端关于此次上传会话的记录数据,然后从本地断开处读取数据进行续传。


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2012年8月6日 10:02
    版主

全部回复

  • 不管下载也好,上传也好,请求主体都是你的客户端,并非服务端。 所以这里就有一个问题,如果是下载的话,我客户端下载了多少,还需要多少,从哪里断开并且连接上,这些信息都是客户端知道的。所以在处理下载断线问题时候,如果服务器支持了断点功能,则是可以断点续传的。  但是上传就不一样了,你请求上传数据到服务端,服务端同意并且它是盲目的接受数据,他并不会实时告诉客户端我接受到哪里了,我还有多少没有接受,我目前需要什么数据,因为所有数据都在客户端,服务端是猜测不了下一步所要的动作和数据的。 如果这个时候,网络断线,则服务端他没有必要帮助客户端维持一个会话,等待你的续传。而客户端也难以控制服务端是否可以接受数据,所有这一切在断线后就需要重新请求和传输。由于主体式客户端,则我们就需要客户端在上传时候进行大量的控制,并且主动提供数据,服务端他是被动接受,所以在此情况下,我们通常都是抛出异常重新进行连接传输。以防传输数据在服务端产生错误。

    你应该要做的是,在你的应用中处理此异常,然后重新请求进行上传。

    ---------------------

    不过也并不是没有断点上传,但是通常我们都需要服务端进行记录上传的数据和维持会话,这样在重新请求后,我们可以先检查服务端关于此次上传会话的记录数据,然后从本地断开处读取数据进行续传。


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2012年8月6日 10:02
    版主
  • 谢谢版本的回复,我也遇到了同样的问题,现在还有一些疑惑

    下载部分:如果服务器支持断线续传,在下载断线,重新连上网络之后,是否需要在程序中重新Set Range才能断点续传,我的程序目前没有设置Range,是从0开始下载的,如果要设置Range,应该如何设置呢,在DownloadOperation中找不到设置Range的API

    上传部分:如果抛出异常,这个UploadOperation就已经停止工作,那么网络恢复后,是需要重新创建新的UploadOperation,再重新请求上传?有没有办法复用原来的UploadOperation呢

    另外我查到通过BackgroundTransferCostPolicy能实现网络状态改变时的控制,可以自动pause和resume,这种网络状态的变化应该也会导致底层socket的断开,那么在这种情况下BackGroundTransfer中是如何无缝的pause和resume呢

    敬请赐教,谢谢~

    2012年8月7日 2:27
  • 下载部分: 这里 DownloadOperation 中可以通过 SetRequestHeader 方法来自定义请求头,文档中描述了一句,当服务器支持接收Range 请求时候,Resume可以进行续传,否则就重头开始下载。(http://msdn.microsoft.com/en-us/library/windows/apps/windows.networking.backgroundtransfer.downloadoperation.resume

    上传部分:使用原来的UploadOperation没有什么意义,因为你还是需要重新上传所有数据。

    〉〉BackGroundTransfer中是如何无缝的pause和resume呢

    CostPolicy 是基于网络状态,如果你设置了Default,则如果在按流量计费的网络下,则BackGroundTransfer进行暂停,当切换到无限制网络,就会恢复传输。BackGroundTransfer的暂停和恢复是高层的动作,对于底层socket链路是透明的。


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2012年8月7日 4:00
    版主
  •          版主,你好!还是下载部分的断点续传的问题,在BackgroundTransfer中只有BackgroundDownloader有 SetRequestHeader 方法,而DownloadOperation 是没有这个方法的,我在一开始创建BackgroundDownloader downloader对象的时候,设置了downloader.SetRequestHeader ("Range","bytes=7340032-");然后创建DownloadOperation download =downloader.CreateDownload(),这样可以知道服务器返回的Content-Range 是bytes 7340032-732381746/732381747,而且StatusCode=206说明服务器接受了Range,但是下载的过程中去Pause().Resume()操作,还是从0开始下载,这是为什么呢?

            还有DownloadOperation 没有SetRequestHeader 方法,那在下载过程中怎么向服务器发送新的请求呢?

           敬请赐教,谢谢~

         

    2012年8月9日 6:20