如何使用socket编程 实现文件的断点续传 记录上传偏移量 c语言

如何使用socket编程 实现文件的断点续传 记录上传偏移量 c语言,第1张

断点续传一般是把文件分成固定大小的包,比如128字节为1个包,然后客户端记录下传了多少个完整的包,断了以后,下次再连接的时候直接请求从前一个包那里传。

批量传输,把整个要传输的文件分成N个部分,然后启动N个线程,每个线程负责下载1部分。这样就达到充分利用网络带宽了。

没有看到具体的程序和出错信息,不太好判断。但是根据字符串长度:

len = 109746785321345

来看。这么长的“字符串长度”通常有2种可能:

是一个(可能不是很大的)负数;

程序内存出错,引用了一段非法的地址,导致读取了错误的字符串长度。

你可以根据实际的情况,看看具体是哪种情况。从你描述的:“客户端退出再重新进行”就不会出错的情况看,有可能是在执行“续传”的相关代码出现了“没有初始化就使用”的变量,或者引用已经free掉的无效内存块的情况。

查查看,有情况继续交流,谢谢。

顾名思义 断点续传就是在上一次下载时断开的位置开始继续下载 在HTTP协议中 可以在请求报文头中加入Range段 来表示客户机希望从何处继续下载

断点续传的原理

在了解HTTP断点续传的原理之前 先来说说HTTP协议 HTTP协议是一种基于tcp的简单协议 分为请求和回复两种 请求协议是由客户机(浏览器)向服务器(WEB SERVER)提交请求时发送报文的协议 回复协议是由服务器(web server) 向客户机(浏览器)回复报文时的协议 请求和回复协议都由头和体组成 头和体之间以一行空行为分隔

以下是一个请求报文与相应的回复报文的例子

GET /image/index_r _c jpg HTTP/ Accept: */* Referer: Accept Language: zh cn Accept Encoding: gzip deflate User Agent: Mozilla/ (patibleMSIE Windows NT NET CLR ) Host: : Connection: Keep Alive HTTP/ OK Server: Microsoft IIS/ Date: Tue Jun : : GMT Content Type: image/jpeg Accept Ranges: bytes Last Modified: Thu May : : GMT ETag: bec eb c : Content Length: JFIF H H nbspC [ ] …

下面我们就来说说 断点续传

顾名思义 断点续传就是在上一次下载时断开的位置开始继续下载 在HTTP协议中 可以在请求报文头中加入Range段 来表示客户机希望从何处继续下载

比如说从第 字节开始下载 请求报文如下

GET /image/index_r _c jpg HTTP/ Accept: */* Referer: Accept Language: zh cn Accept Encoding: gzip deflate User Agent: Mozilla/ (patibleMSIE Windows NT NET CLR ) Host: : Range:bytes= Connection: Keep Alive

NET中的相关类

明白了上面的原理 那么 我们来看看 NET FRAMEWORK中为我们提供了哪些类可以来做这些事

完成HTTP请求

System Net HttpWebRequest

HttpWebRequest 类对 WebRequest 中定义的属性和方法提供支持 也对使用户能够直接与使用 HTTP 的服务器交互的附加属性和方法提供支持

HttpWebRequest 将发送到 Internet 资源的公共 HTTP 标头值公开为属性 由方法或系统设置 下表包含完整列表 可以将 Headers 属性中的其他标头设置为名称/值对 但是注意 某些公共标头被视为受限制的 它们或者直接由 API公开 或者受到系统保护 不能被更改 Range也属于被保护之列 不过 NET为开发者提供了更方便的 *** 作 就是 AddRange方法 向请求添加从请求数据的开始处或结束处的特定范围的字节范围标头

完成文件访问

System IO FileStream

FileStream 对象支持使用Seek方法对文件进行随机访问 Seek 允许将读取/写入位置移动到文件中的任意位置 这是通过字节偏移参考点参数完成的 字节偏移量是相对于查找参考点而言的 该参考点可以是基础文件的开始 当前位置或结尾 分别由SeekOrigin类的三个属性表示

代码实现

了解了 NET提供的相关的类 那么 我们就可以方便的实现了

代码如下

static void Main(string[] args) {  string StrFileName= c:\\aa zip //根据实际情况设置   string StrUrl= //根据实际情况设置  //打开上次下载的文件或新建文件  long lStartPos =  System IO FileStream fs if (System IO File Exists(StrFileName))  {  fs= System IO File OpenWrite(StrFileName) lStartPos=fs Length fs Seek(lStartPos System IO SeekOrigin Current)//移动文件流中的当前指针  }  else  { fs = new System IO FileStream(StrFileName System IO FileMode Create) lStartPos =  }  //打开网络连接   try  {  System Net HttpWebRequest request =(System Net HttpWebRequest)System Net HttpWebRequest Create(StrUrl) if ( lStartPos>)  request AddRange((int)lStartPos)//设置Range值  //向服务器请求 获得服务器回应数据流  System IO Stream ns= request GetResponse() GetResponseStream() byte[] nbytes = new byte[ ] int nReadSize=  nReadSize=ns Read(nbytes ) while( nReadSize > )  {  fs Write(nbytes nReadSize) nReadSize=ns Read(nbytes ) }  fs Close() ns Close() Console WriteLine( 下载完成 ) }  catch(Exception ex)  {  fs Close() Console WriteLine( 下载过程中出现错误: +ex ToString()) }  }

lishixinzhi/Article/program/net/201311/13111


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/11516803.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-16
下一篇 2023-05-16

发表评论

登录后才能评论

评论列表(0条)

保存