2013-05-20 25 views
2

我尝试使用c和套接字编写自己的下载管理器,现在发生了一些奇怪的事情,我真的无法解释为什么。由自编码的下载管理器使用套接字下载后截断的tar.gz archieve使用套接字

所以我做的是:我创建套接字,连接到服务器,创建并发送GET请求。到目前为止,万物都很好。下载开始,当它完成时,我搜索字节(char)数组''\ n \ r \ n'以到达标题的末尾(对于消息主体的开始还有一个)。 从那里我写msg_size-(header_end + 1)字节到一个文件。生成的文件具有完全相同的字节大小,就像我正常下载文件一样。但是当我尝试提取它时,它出现“文件意外结束”错误,而另一个版本提取得很好。

有没有人可能有解释,我也可以提供代码,我只是不知道 问题可以在哪里,所以我试图首先表达问题。 我尝试了所有的“wb”和“w”标志。

此外,服务器不指定分块传输或压缩编码。 虽然是http/1.1。

谢谢!

编辑: 所以这是服务器部首:

HTTP/1.1 200 OK 
Date: Mon, 20 May 2013 16:33:26 GMT 
Server: Apache/2.2.9 (Debian) 
Last-Modified: Sun, 17 Jan 2010 18:17:39 GMT 
ETag: "3ba006-29b376-47d60407b56c0" 
Accept-Ranges: bytes 
Content-Length: 2732918 
Content-Type: application/x-gzip 

EDIT2; 这是我收到并写入文件:

memset(file,0,file_size); 
    arg[1]=recv(socketfd,file,file_size,0); 
    int mstart=0; 
    while(file[mstart]!='\n' ||file[mstart+1]!='\r'|| file[mstart+2]!='\n'){ 
     mstart++; 
    } 
    mstart+=3; 
    fsize=file_size; 
    int fsize=file_size-mstart;  //file_size from Response Header 
    fwrite(&(file[mstart]),1,fsize,fd); 
    fclose(fd) 

确定,这使得有很大的意义,所以我现在尝试这样做: (编辑)错在那里,但是这也并不工作:

fd=fopen(file_name,"wb"); 
    memset(file,0,file_size); 
    recv(socketfd,file,3,0); 
    while(1==1){ 
    if(file[0]=='\n' ||file[1]=='\r'|| file[2]=='\n'){ 
     recv(socketfd,file,3,0); 
    }else{ 
     break; 
    } 
    } 
    arg[1]=recv(socketfd,file,file_size,MSG_WAITALL); 
    fwrite(file,1,file_size,fd); 
    fclose(fd); 

但它现在仍在使用

最后!这个作品知道,非常感谢你!

fd=fopen(file_name,"w"); 
    memset(file,0,file_size); 
    recv(socketfd,file,3,0); 
    while(file[0]!='\n' ||file[1]!='\r'|| file[2]!='\n'){ 
     recv(socketfd,file,3,0); 
    } 
    arg[1]=recv(socketfd,file,file_size,MSG_WAITALL); 
    fwrite(file,1,file_size,fd); 
    fclose(fd); 
+0

当你确定你正在限制START和EOF文件时? –

+0

“Content-Type”和/或“Content-Transfer-Encoding”标题说了什么? –

+0

使用像md5sum这样的校验和程序来验证这两个文件是否相同。你也可以使用'diff'(如果你在windows上使用windiff)来查看你下载的.tar.gz与原始.tar之间的区别。gz会告诉你问题在哪里出现;看到用于转储文件的读/写循环会很有用;同样作为一个实验,您可以手动编写ENTIRE对文件的回复和(第1次测试),然后(第2次测试)作为单独的文件内容自动编写,这样您可以调试正确的东西。 –

回答

1

您的文件读取逻辑不起作用。您首先需要阅读一些固定金额,并解析该固定金额以查找标题的结尾。然后解析标题以查找内容长度。然后,您已经读过的任何数据都会被读出,作为文件的第一部分。文件的其余部分是内容长度减去你写的内容。这是更多的字节,你必须从套接字读取并写入文件。

你的问题是你没有正确使用内容长度头(你从前面的HEAD请求中提取的)。它表示标题后面传输的大小,而不是整个响应的长度。

文件似乎是正确尺寸的原因是,你写了正确的字节数,但你正在阅读的过去,你从套接字读取(字节结束,因为你已经调整mstart着过去头的末尾)。

+0

谢谢!坏我不能upvote你 – zabeltech

相关问题