麻烦最好写点代码看看?分不够再开贴散分 都来讨论下啊

解决方案 »

  1.   

        当CuteFTP、GetRight软件刚刚问世的时候,我觉得断点续传非常神奇,它们肯定采用了什么高深的技术,不过认真一研究,发现也没有什么特别了不起的。断点续传的实质就是能在下载时自由指定下载的启始位置。 
        要实现FTP的断点续传,FTP服务器必须支持REST指令,这条指令在FTP协议文本RFC959中就已经定义了,不过它不是FTP服务器必须支持的指令。一般,你可以在下载前使用REST 100命令进行实验,如果服务器正常执行了这条命令,说明该服务器支持FTP断点续传。REST后面跟的数表示下载文件的起始位置,而REST 0表示从文件最开始处下载。REST命令本身并不执行下载功能,你仍需要使用RETR命令执行下载工作。 
        要实现HTTP断点续传,Web服务器必须支持HTTP/1.1(协议文本为RFC2068),当然也不是所有支持HTTP/1.1的服务器都实现了HTTP断点续传。一般在正常的Header之外,还要在Header中加上如下几句: 
        Connection: close 
        Host: www.host.com 
        Range: bytes=1-100 
        这里的Range就是指定下载范围,也可以使用"100-"表示从100开始下载。更详细的内容可以参见RFC2068。 
        上面介绍的是原理,现在一般编程都使用各种控件,所以实现的时候应该具体分析。绝大多数HTTP控件都允许用户修改HTTP的Header,所以HTTP的续传比较容易实现。有的FTP控件不支持REST命令,也有控件通过特殊的属性来实现REST命令,如IP*Works!就使用StartByte属性来实现REST的功能。 
        VB本身包括的Internet Transfer Control不能实现FTP的断点传续,因为不支持REST命令,但执行Execute 方法时利用requestHeaders参数可以实现HTTP的断点传续
      

  2.   

    网络本身不提供断点续传
    但是通过协议可以实现
    比如FTP
      

  3.   

    那点点的通讯软件中实现的断点续传没有使用ftp啊 怎么通过编程实现啊 
    似乎我讨论的问题 这里没人能回答吗? 还是高手觉得这太简单了?
    这里主要针对p2p软件的技术讨论
      

  4.   

    自己做的时候,在传送前应该是有对话的,在对话中多加一条命令,用于表示下载的起启位置就可以了,比如:如果命令格式 DownLoad+起始位置,那下载方发送一条 DownLoad1024,服务器方分析命令后得知是下载文件,并且从1024字节开始,那么这个时候服务器打开指定的文件,并定位到1024位置,然后开始传送就可以了。
      

  5.   

    不需要多线程,用Winsock控件数组。
    给你看看我写的断点续传WebServer的相关代码
                '打开文件
                
                Dim Times, LastBytes
                Dim DataLength As Long
                Dim i As Long
                
                If Request.iStartPos = "" Then Request.iStartPos = 0
                Request.iStartPos = CLng(Request.iStartPos)
                
                '获取文件长度
                
                DataLength = FileLen(szFullPath)
                '计算发送次数
                Times = Int((DataLength - Request.iStartPos) / mBufferSize)
                LastBytes = (DataLength - Request.iStartPos) Mod mBufferSize
                
                
                
                '定义缓冲
                
                Dim szDatas() As Byte
                Dim szData() As Byte
                ReDim szDatas(mBufferSize) As Byte
                ReDim szData(LastBytes) As Byte
                
                '获取文件类型
                szTemp = Request.szTarget
                If InStr(szTemp, ".") Then
                    Dim szType As String
                    For i = Len(szTemp) To 1 Step -1
                        If Mid(szTemp, i, 1) = "." Then Exit For
                        szType = Mid(szTemp, i, 1) & szType
                    Next
                End If
                szType = GetMIMEByExt(szType)
                
                If Not Request.iStartPos = 1 Then
                HttpHead = "HTTP/1.1 206 Partial content" & vbCrLf
                HttpHead = HttpHead & "Server: " & mServer.ServerName & vbCrLf
                HttpHead = HttpHead & "Connection: close" & vbCrLf
                HttpHead = HttpHead & "Content-Type: " & szType & vbCrLf
                HttpHead = HttpHead & "Content-Length: " & DataLength - Request.iStartPos & vbCrLf
                HttpHead = HttpHead & "Content-Range: bytes " & Request.iStartPos & "-" & DataLength - 1 & "/" & DataLength & vbCrLf
                HttpHead = HttpHead & vbCrLf
                Else
                HttpHead = "HTTP/1.1 200 OK" & vbCrLf
                HttpHead = HttpHead & "Server: " & mServer.ServerName & vbCrLf
                HttpHead = HttpHead & "Accept-Ranges: bytes" & vbCrLf
                HttpHead = HttpHead & "Connection: close" & vbCrLf
                HttpHead = HttpHead & "Content-Type: " & szType & vbCrLf
                HttpHead = HttpHead & "Content-Length: " & DataLength & vbCrLf
                HttpHead = HttpHead & vbCrLf
                End If
                
                
                '发送HTTP头
                frmMain.Socket(Index).SendData HttpHead
                
                DoEvents
                
                '打开文件
                Open szFullPath For Binary As FreeHandle
                Seek FreeHandle, Request.iStartPos + 1
                For i = 1 To Times
                    Get FreeHandle, , szDatas()
                    frmMain.Socket(Index).SendData szDatas()
                    DoEvents
                Next
                
                Get FreeHandle, , szData()
                frmMain.Socket(Index).SendData szData()
                DoEvents
                Close FreeHandle
                DoEvents
      

  6.   

    我写的是HTTPServer,客户端当然按照HTTP协议请求资源然后接收数据,就像 FlashGet, IE一样。 FlashGet是多线程下载的。其实就是不同的线程下载不同的文件数据区域,例如一个文件 1000K, 5个线程
    线程一下载: 1-200K
    线程二下载: 201-400K
    线程三下载: 401-600K
    线程四下载: 601-800K
    线程五下载: 801-1000K用Winsock控件数组, 你可以用 Winsock(0) 来监听,然后每接收到一个连接请求分配一个空闲的Winsock给他连接上,然后每个Winsock有独立的事件驱动工作,相当于并行工作。
      

  7.   

    哦 谢谢了啊 启发很大 虽然不明白 为什么ftp只需要一个端口 如果你知道也请顺便讲下
    还有个问题就是p2p的传输 用udp还是tcp好些啊?
      

  8.   

    监听是只需要一个端口的,就是21。但是你和ftp连接上的端口并不是21,因为21只是用来接收请求的端口,如果被占用了就不能得到其他用户的请求。所以他会随机开一个端口和你连接。p2p用TCP好,我留意了QQ的传送文件,如果文件小的话,通常用UDP,文件大的话,就用TCP,因为UDP不需要连接,谁都可以发送数据到那个端口,如果期间刚好有哪个无聊的人向这个端口发送了一些杂乱数据,就干扰了正常的文件数据传送。
      

  9.   

    我自己up一下  我想把文件拆分了 再多线程发送这些小文件 然后接收后合并 大家觉得如何?还是直接打开文件 从不同位置读取 多个winsock并发? 那中方法好点呢?
      

  10.   

    后者,不需要拆分这么麻烦,如果先拆分就多了额外的时间,降低了效率,特别是大文件。IIS是直接打开文件从不同位置读取的。
      

  11.   

    你是写的webserver 我是p2p啊 呵呵 拆分是有额外时间 但是直接发的话 断点续传的定位就好象麻烦多了 而且这种方式处理实际是多个文件并发 这样的话 如果是几个小文件 就不分割 直接一次性发出去 那样也不必发好几次了
      

  12.   

    定位不会太麻烦,用seek定位即可.另外HTTP协议是现成的,参考也未尝不可.
    如果你要拆分,那就有这样的问题:如果是大文件,拆出来就占用了硬盘空间..况且VB的效率..
    如果拆成小文件,那就要拆很多个,一个100M的如果1M一个要拆100个,如果拆5M一个也可,不过那断点续传该称为"断段续传"
      

  13.   

    我知道定位用seek 但是多个线程的定位怎么处理  我还没想好啊 因为同一个文件如果从不同的位置开始 再在不同位置结束 从新开始的定位 我还没思路啊 因为中断以后文件在不同线程所写数据中间 有空的 没写完的数据 这部分怎么处理 乱七八糟的
      

  14.   

    长期招聘计算机安装调试人员及专、兼职程序员(北京)
    程序员要求
    熟悉VB的socket通讯、数据库(任意)
    联系方式
    [email protected]
    13301116100李先生
      

  15.   

    刚测试了下 空字符也会被seek计算在内 这样续传后的定位 不好处理阿  Garfield你用QQ还是msn? 留一下 方便交流
      

  16.   

    呵呵  我有点愚蠢了 写个log记录下断点的位置就行了 
    ok 结贴了 谢谢大家参加讨论