您的位置:首页 > 理论基础 > 计算机网络

Linux下Socket写http协议下载文件代码以及说明

2010-07-07 22:46 387 查看
项目一部分需要使用socket写http协议,并下载文件,看似简单得问题,调试起来确有一些小小得问题,如果是windows平台的话,自然会简单很多,一个DownloadFile API就可以搞定,可是客户得Proj是在Linux下,不得已,从头开发了。目前得代码由于依然在win下面调试,所以移植得时候稍微注意一下就可以了。

看代码:

view plaincopy to clipboardprint?

#include <string>   

#include <iostream>   

#include <stdio.h>   

#include <winsock.h>   

#include <conio.h>   

  

  

using namespace std;   

  

#pragma comment("ws2_32.lib")   

  

string host2ip(const string& strdomain);   

void save2file(char *buffer,const string& filename);   

int getlength(const string& sheader);   

bool getstatus(const string& sheader);   

int getleftlength(const string& sheader);   

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

  

  

int port = 80;   

int error=0;   

string serveraddr;   

int i = 0;   

const int BUFFER_SIZE = 1024;   

char buffer[BUFFER_SIZE] = {0};   

char    msg[BUFFER_SIZE];   

FILE *f;   

const string file = "/BT/200801/3/117906.torrent";   

const string url = "www.supbt.com";   

const string filename = "117906.torrent";   

  

  

int main(void)   

{   

        int      r;   

        WSADATA  wsa;   

        SOCKET   sock;   

        struct   sockaddr_in sin;   

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

        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);   

                return -1;   

        }   

  

        string header = string(buffer);   

        int ilength = getlength(header);   

        int leftlength = ilength;   

        int icount;   

        if(getstatus(header)){   

                //current is r   

                char *q = buffer;   

                char *p = strstr(buffer, "/r/n/r/n");   

  

                p += 4;   

                //注意这里得 r - (p-q) 非常关键得问题   

                fwrite(p,r - (p - q),1,f);   

                leftlength -= r - (p - q);   

                int i=0;   

                icount = r - (p - q);   

                while(true)   

                {   

                        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;    //209  100 100 92   

                        leftlength -= r;   

                        if(leftlength > 0){   

                                fwrite(buffer,r,1,f);   

                                icount += r;   

                        }   

                        else if(leftlength == 0){   

                                //   

                                break;   

                        }   

                        else{   

                                icount += tmp;   

                                fwrite(buffer,tmp,1,f);   

                                break;   

                        }   

                        cout << i++ << " r is "<< r << endl;   

  

                }   

        }else{   

                cout << "http protocal error" << endl;   

        }   

        cout << icount << endl;   

        fclose(f);   

        closesocket(sock);   

        WSACleanup();   

        getche();   

        return 0;   

}   

/*  

构造HTTP头  

*/  

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-Language: zh-cn");   

        //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");   

}   

//---------------------------------------------------------------------------   

  

/*   

将domain 转换为IP地址   

*/   

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){   

        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;   

}   

/*  

该方法判断是否Get成功,不成功就取消下载文件  

*/  

bool getstatus(const string& sheader){   

        string start = "HTTP/1.1 200 OK";   

        if(sheader.find(start,0) != string::npos){   

                return true;   

        }   

        else{   

                return false;   

        }   

}   

/*  

该方法并没有用到,开始考虑多了  

*/  

int getleftlength(const string& sheader){   

        int nreturnl = 0;   

        int ilength = sheader.length();   

        string _send = "/r/n/r/n";   

        int istart = sheader.find_last_of(_send);   

        if(istart != string::npos){   

                nreturnl = ilength - istart -_send.length();   

        }   

        return nreturnl;   

}   
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐