请教socket写Http协议直接下载文件问题[全代码]

huzhangyou 2008-02-10 11:18:05
1:问题先说

下载数据正常,可是不知何处出问题导致格式不对。请教高手们

代码:

#include <string>
#include <iostream>
#include <stdio.h>
#include <winsock.h>
#include <conio.h>


using namespace std;

#pragma comment("ws2_32.lib")

string serveraddr;
string host2ip(const string& strdomain);
void save2file(char *buffer,const string& filename);
int getlength(const string& sheader);
int port = 80;
int error=0;

int i = 0;
const int BUFFER_SIZE = 1024;
char buffer[BUFFER_SIZE] = {0};
char msg[BUFFER_SIZE];
const string file = "/BT/200802/1/118909.torrent";
const string url = "www.supbt.com";
const string filename = "1234.torrent";
FILE *f;


void sethttphead(const string& file,const string& server);

int main()
{
int r;
WSADATA wsa;
SOCKET sock;
struct sockaddr_in sin;
f = fopen(filename.c_str(),"a");
sethttphead(file,url);
if(WSAStartup(MAKEWORD(2,2),&wsa))
{
printf("WSAStartup Error: %d\n",WSAGetLastError());
getche();
return -1;
}

if((sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==INVALID_SOCKET)
{
printf("Socket Error: %d\n",WSAGetLastError());
getche();
return -1;
}

sin.sin_family=AF_INET;
sin.sin_port=htons(port);
serveraddr = host2ip(url);

cout << serveraddr << endl;
sin.sin_addr.s_addr=inet_addr(serveraddr.c_str());


if(connect(sock,(struct sockaddr *)&sin,sizeof(sin))==SOCKET_ERROR)
{
printf("Connect Error: %d\n",WSAGetLastError());
printf("请检测网络连接!\n");
getche();
return -1;
}


if((r=send(sock,msg,sizeof(msg),0))==SOCKET_ERROR)
{
printf("Send Error: %d\n",WSAGetLastError());
getche();
return -1;
}

memset(buffer,0,BUFFER_SIZE);
if((r=recv(sock,buffer,BUFFER_SIZE,0))==SOCKET_ERROR)
{
printf("Recv Error: %d\n",WSAGetLastError());
closesocket(sock);
//getche();
return -1;
}

string header = string(buffer);
int ilength = getlength(header);
int leftlength = ilength;
cout << ilength << endl;
//getfilelength

char *p = strstr(buffer, "\r\n\r\n");
p += 4;
fwrite(p,strlen(p),1,f);
leftlength -= strlen(p);
int i=0;
int count = strlen(p);
while(true)
{
//if(leftlength > 0)
memset(buffer, 0, BUFFER_SIZE);
r = recv(sock, buffer, BUFFER_SIZE, 0);

if (r < 0) {
closesocket(sock);
return 2;
}
if (r == 0) {
break;
}
int tmp;
tmp = leftlength;
leftlength -= r;
if(leftlength > 0){
fwrite(buffer,r,1,f);
count += r;
}
else if(leftlength == 0){
//
}
else{
cout << buffer << endl;

string s = string(buffer);
cout << "haha" << endl;
cout << s.substr(0,tmp+3) << endl;
count += tmp;
fwrite(buffer,tmp+3,1,f);
}
//cout << buffer << endl;
cout << i++ << " r is "<< r << endl;

}
cout << count << endl;
fclose(f);
closesocket(sock);
WSACleanup();
getche();
return 0;
}

void sethttphead(const string& file,const string& server)
{
strcat(msg,"GET ");
strcat(msg,file.c_str());

strcat(msg," HTTP/1.1");
strcat(msg,"\r\n");

strcat(msg,"Accept:*/*");
strcat(msg,"\r\n");


strcat(msg,"Accept-Encoding: gzip, deflate");
strcat(msg,"\r\n");

strcat(msg,"User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)");
strcat(msg,"\r\n");

strcat(msg,"Host:");
strcat(msg,server.c_str());
strcat(msg,"\r\n");

strcat(msg,"Connection: Keep-Alive");
strcat(msg,"\r\n");
strcat(msg,"\r\n");
}
//---------------------------------------------------------------------------


string host2ip(const string& strdomain)
{
SOCKADDR_IN saddr;
WORD wVersionRequested;
WSADATA wsaData;
hostent *pHostIp;
int nErrorNum;
wVersionRequested = MAKEWORD(2, 2);
nErrorNum = WSAStartup(wVersionRequested, &wsaData);
if(nErrorNum != 0)
{
return "";
}
saddr.sin_family = AF_INET;
pHostIp = gethostbyname(strdomain.c_str());
if(pHostIp == NULL)
{
return "0.0.0.0";
}
WSACleanup();
return (string)inet_ntoa(*(LPIN_ADDR)*(pHostIp->h_addr_list));
}

void save2file(char *buffer,const string& filename)
{
FILE *f;
f = fopen(filename.c_str(),"a+");
fwrite(buffer,strlen(buffer),1,f);
fclose(f);
}

int getlength(const string& sheader){
//
/*
int istart = header.find("Content-length:")
int iend =
*/
char * cont_len_pos;
unsigned long cont_length;
const char* header = sheader.c_str();

cont_len_pos =(char *)strstr(header,"Content-Length:");
cont_len_pos = (char *)strchr(cont_len_pos,' ');
cont_len_pos++;
sscanf(cont_len_pos, "%ld", &cont_length);

return cont_length;
}
...全文
719 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
felixsxt 2008-06-04
  • 打赏
  • 举报
回复
mark!
yaozhenjiang 2008-03-18
  • 打赏
  • 举报
回复
好,不错不错
yriio 2008-02-11
  • 打赏
  • 举报
回复
打开文件参数用 "ab" 试试看
yriio 2008-02-11
  • 打赏
  • 举报
回复
写文件的时候模式不对了吧??

好比你用文本文件打开了一个torrent文件 再另存为 虽然内容一样 但是打开就是会报错
huzhangyou 2008-02-11
  • 打赏
  • 举报
回复
http://tel.libing.net.cn/post/linux-socket-http-download-file.php
http://www.libing.net.cn/post/linux-socket-http-download-file.php
huzhangyou 2008-02-11
  • 打赏
  • 举报
回复
搞定 我晕 :-)
详细得代码参考我的博客
http://www.libing.net.cn
huzhangyou 2008-02-11
  • 打赏
  • 举报
回复

fwrite(p,strlen(p),1,f);


写入得时候 strlen(p)
总是会多东西 不知道为什么
huzhangyou 2008-02-11
  • 打赏
  • 举报
回复

f = fopen(filename.c_str(),"ab");



偶尔正确 偶尔错误
奇怪了


memset(buffer,0,BUFFER_SIZE);
if((r=recv(sock,buffer,BUFFER_SIZE,0))==SOCKET_ERROR)
{
printf("Recv Error: %d\n",WSAGetLastError());
closesocket(sock);
//getche();
return -1;
}

string header = string(buffer);
int ilength = getlength(header);
int leftlength = ilength;
cout << ilength << endl;
//getfilelength

char *p = strstr(buffer, "\r\n\r\n");
p += 4;
fwrite(p,strlen(p),1,f);
leftlength -= strlen(p);
int i=0;
int count = strlen(p);



问题在第一个包上面
不知道为什么
iambic 2008-02-10
  • 打赏
  • 举报
回复
有啥不对的?写文件用二进制模式了吗?
huzhangyou 2008-02-10
  • 打赏
  • 举报
回复

else{
cout << buffer << endl;

string s = string(buffer);
cout << "haha" << endl;
cout << s.substr(0,tmp+3) << endl;
count += tmp;
fwrite(buffer,tmp+3,1,f);
}


以上代码是错误得,忘记修正了,抱歉

else{
cout << buffer << endl;

string s = string(buffer);
cout << "haha" << endl;
cout << s.substr(0,tmp) << endl;
count += tmp;
fwrite(buffer,tmp,1,f);
}



up
huzhangyou 2008-02-10
  • 打赏
  • 举报
回复
请教大家是否碰到此等情况
非常奇怪
代码中 count 的值 和文件大小相符
所以才觉得奇怪

64,701

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧