纯C++的Socket访问Http封装类

长平狐 发布于 2012/08/13 15:44
阅读 1K+
收藏 0

纯C++的Socket访问Http封装类

1.项目中要使用c++++来访问Web服务器,从网上找了个C++的封装类,其中调用了MFC,在VC2005上用能用,但是移植到VC2003就出问题了,干脆修改成了纯C++的,不敢独享,share之。

2.以下是调用方法:

#include "stdafx.h" 
#include <iostream> 
#include <string> 
#include "http/request.h" 
 
using namespace std; 
 
int _tmain(int argc, _TCHAR* argv[]) 
{ 
    Request myRequest;      //初始化类 
    string sHeaderSend;     //定义http头 
    string sHeaderReceive;  //返回头 
    string sMessage="";     //返回页面内容 
    bool IsPost=false;  //是否Post提交 
 
    int i =myRequest.SendRequest(IsPost, "http://neeao.com", sHeaderSend, 
                                 sHeaderReceive, sMessage); 
    if (i) 
    {    
        cout<<"Http头:"<<endl; 
        cout<< sHeaderSend <<endl; 
        cout<<"响应头"<<endl; 
        cout<< sHeaderReceive <<endl; 
        cout<<"网页内容"<<endl; 
        cout<< sMessage <<endl; 
    }else 
    { 
        cout<<"网络不可到达"<<endl; 
    } 
    system("pause"); 
    return 0; 
} 
 

类代码如下

//******************************************  
//纯C++的socket访问Http封装类,Neeao修改  
//http://neeao.com  
//2009-08-25  
//******************************************  
 
#if !defined(AFX_REQUEST_H__9F2C9BB6_CBA7_40AF_80A4_09A1CE1CE220__INCLUDED_)  
#define AFX_REQUEST_H__9F2C9BB6_CBA7_40AF_80A4_09A1CE1CE220__INCLUDED_  
 
#if _MSC_VER > 1000  
#pragma once  
#endif // _MSC_VER > 1000  
 
 
#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <winsock2.h>  
#pragma comment(lib, "WS2_32")   
 
using namespace std;  
#define MEM_BUFFER_SIZE 10  
 
/*   
    HTTPRequest: Structure that returns the HTTP headers and message  
                    from the request  
*/  
typedef struct 
{   
    LPSTR headerSend;                               // Pointer to HTTP header Send   
    LPSTR headerReceive;                            // Pointer to HTTP headers Receive  
    LPSTR message;                                  // Pointer to the HTTP message   
    long messageLength;                             // Length of the message   
} HTTPRequest;  
 
/*   
    MemBuffer:  Structure used to implement a memory buffer, which is a  
                buffer of memory that will grow to hold variable sized  
                parts of the HTTP message.   
*/ 
typedef struct 
{  
    unsigned    char *buffer;  
    unsigned    char *position;  
    size_t      size;  
} MemBuffer;  
 
 
class Request    
{  
public:  
    Request();  
    virtual ~Request();  
 
private:  
    void        MemBufferCreate(MemBuffer *b);  
    void        MemBufferGrow(MemBuffer *b);  
    void        MemBufferAddByte(MemBuffer *b, unsigned char byt);  
    void        MemBufferAddBuffer(MemBuffer *b, unsigned char *buffer, size_t size);  
    DWORD       GetHostAddress(LPCSTR host);  
    void        SendString(SOCKET sock,LPCSTR str);  
    BOOL        ValidHostChar(char ch);  
    void        ParseURL(string url,LPSTR protocol,int lprotocol, LPSTR host,int lhost,LPSTR request,int lrequest,int *port);  
 
    int         SendHTTP(string url,LPCSTR headerReceive,BYTE *post, DWORD postLength,HTTPRequest *req);  
 
public:  
    int     SendRequest(bool IsPost, string url, string& psHeaderSend, string& pszHeaderReceive,string& pszMessage);  
};  
 
#endif // !defined(AFX_REQUEST_H__9F2C9BB6_CBA7_40AF_80A4_09A1CE1CE220__INCLUDED_)  
Request.cpp
 
//******************************************  
//纯C++的Socket访问Http封装类,Neeao修改  
//http://neeao.com  
//2009-08-25  
//******************************************  
 
 
#include "stdafx.h"  
#include "Request.h"  
#include <string>  
#ifdef _DEBUG  
#undef THIS_FILE  
static char THIS_FILE[]=__FILE__;  
#define new DEBUG_NEW  
#endif  
 
 
//////////////////////////////////////////////////////////////////////  
// Construction/Destruction  
//////////////////////////////////////////////////////////////////////  
 
Request::Request()  
{  
 
}  
 
Request::~Request()  
{  
 
}  
 
 
//*******************************************************************************************************  
//MemBufferCreate:   
//                  Passed a MemBuffer structure, will allocate a memory buffer   
//                   of MEM_BUFFER_SIZE.  This buffer can then grow as needed.  
//*******************************************************************************************************  
void Request::MemBufferCreate(MemBuffer *b)  
{  
    b->size = MEM_BUFFER_SIZE;  
    b->buffer =(unsigned    char *) malloc( b->size );  
    b->position = b->buffer;  
}  
 
//*******************************************************************************************************  
// MemBufferGrow:    
//                  Double the size of the buffer that was passed to this function.   
//*******************************************************************************************************  
void Request::MemBufferGrow(MemBuffer *b)  
{  
    size_t sz;  
    sz = b->position - b->buffer;  
    b->size = b->size *2;  
    b->buffer =(unsigned    char *) realloc(b->buffer,b->size);  
    b->position = b->buffer + sz;   // readjust current position  
}  
 
//*******************************************************************************************************  
// MemBufferAddByte:   
//                  Add a single byte to the memory buffer, grow if needed.  
//*******************************************************************************************************  
void Request::MemBufferAddByte(MemBuffer *b,unsigned char byt)  
{  
    if( (size_t)(b->position-b->buffer) >= b->size )  
        MemBufferGrow(b);  
 
    *(b->position++) = byt;  
}  
 
//*******************************************************************************************************  
// MemBufferAddBuffer:  
//                  Add a range of bytes to the memory buffer, grow if needed.  
//*******************************************************************************************************  
void Request::MemBufferAddBuffer(MemBuffer *b,  
                                 unsigned char *buffer, size_t size)  
{  
    while( ((size_t)(b->position-b->buffer)+size) >= b->size )  
        MemBufferGrow(b);  
 
    memcpy(b->position,buffer,size);  
    b->position+=size;  
}  
 
//*******************************************************************************************************  
// GetHostAddress:   
//                  Resolve using DNS or similar(WINS,etc) the IP   
//                   address for a domain name such as www.wdj.com.   
//*******************************************************************************************************  
DWORD Request::GetHostAddress(LPCSTR host)  
{  
    struct hostent *phe;  
    char *p;  
 
    phe = gethostbyname( host );  
 
    if(phe==NULL)  
        return 0;  
 
    p = *phe->h_addr_list;  
    return *((DWORD*)p);  
}  
 
//*******************************************************************************************************  
// SendString:   
//                  Send a string(null terminated) over the specified socket.  
//*******************************************************************************************************  
void Request::SendString(SOCKET sock,LPCSTR str)  
{  
    send(sock,str,strlen(str),0);  
}  
 
//*******************************************************************************************************  
// ValidHostChar:   
//                  Return TRUE if the specified character is valid  
//                      for a host name, i.e. A-Z or 0-9 or -.:   
//*******************************************************************************************************  
BOOL Request::ValidHostChar(char ch)  
{  
    return( isalpha(ch) || isdigit(ch)  
        || ch=='-' || ch=='.' || ch==':' );  
}  
 
 
//*******************************************************************************************************  
// ParseURL:   
//                  Used to break apart a URL such as   
//                      http://www.localhost.com:80/TestPost.htm into protocol, port, host and request.  
//*******************************************************************************************************  
void Request::ParseURL(string url,LPSTR protocol,int lprotocol,LPSTR host,int lhost,LPSTR request,int lrequest,int *port)  
{  
    char *work,*ptr,*ptr2;  
 
    *protocol = *host = *request = 0;  
    *port=80;  
 
    work = strdup(url.c_str());  
    strupr(work);  
 
    ptr = strchr(work,':');                         // find protocol if any  
    if(ptr!=NULL)  
    {  
        *(ptr++) = 0;  
        lstrcpyn(protocol,work,lprotocol);  
    }  
    else 
    {  
        lstrcpyn(protocol,"HTTP",lprotocol);  
        ptr = work;  
    }  
 
    if( (*ptr=='/') && (*(ptr+1)=='/') )            // skip past opening /'s   
        ptr+=2;  
 
    ptr2 = ptr;                                     // find host  
    while( ValidHostChar(*ptr2) && *ptr2 )  
        ptr2++;  
 
    *ptr2=0;  
    lstrcpyn(host,ptr,lhost);  
 
    lstrcpyn(request,url.c_str() + (ptr2-work),lrequest);   // find the request  
 
    ptr = strchr(host,':');                         // find the port number, if any  
    if(ptr!=NULL)  
    {  
        *ptr=0;  
        *port = atoi(ptr+1);  
    }  
 
    free(work);  
}  
 
//*******************************************************************************************************  
// SendHTTP:   
//                  Main entry point for this code.    
//                    url           - The URL to GET/POST to/from.  
//                    headerSend        - Headers to be sent to the server.  
//                    post          - Data to be posted to the server, NULL if GET.  
//                    postLength    - Length of data to post.  
//                    req           - Contains the message and headerSend sent by the server.  
//  
//                    returns 1 on failure, 0 on success.  
//*******************************************************************************************************  
int Request::SendHTTP(string url,LPCSTR headerReceive,BYTE *post,  
                      DWORD postLength,HTTPRequest *req)  
{  
    WSADATA         WsaData;  
    SOCKADDR_IN     sin;  
    SOCKET          sock;  
    char            buffer[512];  
    char            protocol[20],host[256],request[1024];  
    int             l,port,chars,err;  
    MemBuffer       headersBuffer,messageBuffer;  
    char            headerSend[1024];  
    BOOL            done;  
 
 
 
 
    ParseURL(url,protocol,sizeof(protocol),host,sizeof(host),       // Parse the URL  
        request,sizeof(request),&port);  
    if(strcmp(protocol,"HTTP"))  
        return 1;  
 
    err = WSAStartup (0x0101, &WsaData);                            // Init Winsock  
    if(err!=0)  
        return 1;  
 
    sock = socket (AF_INET, SOCK_STREAM, 0);  
    //if (socket == INVALID_SOCKET)  
    if (sock == INVALID_SOCKET)  
    {  
        return 1;  
    }  
 
    sin.sin_family = AF_INET;                                       //Connect to web sever  
    sin.sin_port = htons( (unsigned short)port );  
    sin.sin_addr.s_addr = GetHostAddress(host);  
 
    if( connect (sock,(LPSOCKADDR)&sin, sizeof(SOCKADDR_IN) ) )  
    {  
 
        return 1;  
    }  
 
 
    if( !*request )  
        lstrcpyn(request,"/",sizeof(request));  
 
    if( post == NULL )  
    {  
        SendString(sock,"GET ");  
        strcpy(headerSend, "GET ");  
    }  
    else   
    {  
        SendString(sock,"POST ");  
        strcpy(headerSend, "POST ");  
    }  
    SendString(sock,request);  
    strcat(headerSend, request);  
 
    SendString(sock," HTTP/1.0/r/n");  
    strcat(headerSend, " HTTP/1.0/r/n");  
 
    SendString(sock,"Accept: image/gif, image/x-xbitmap," 
        " image/jpeg, image/pjpeg, application/vnd.ms-excel," 
        " application/msword, application/vnd.ms-powerpoint," 
        " */*/r/n");  
    strcat(headerSend, "Accept: image/gif, image/x-xbitmap," 
        " image/jpeg, image/pjpeg, application/vnd.ms-excel," 
        " application/msword, application/vnd.ms-powerpoint," 
        " */*/r/n");  
 
    SendString(sock,"Accept-Language: en-us/r/n");  
    strcat(headerSend, "Accept-Language: en-us/r/n");  
 
    SendString(sock,"Accept-Encoding: gzip, default/r/n");  
    strcat(headerSend, "Accept-Encoding: gzip, default/r/n");  
 
    SendString(sock,"User-Agent: Neeao/4.0/r/n");  
    strcat(headerSend, "User-Agent: Neeao/4.0/r/n");  
 
    if(postLength)  
    {  
        sprintf(buffer,"Content-Length: %ld/r/n",postLength);  
        SendString(sock,buffer);  
        strcat(headerSend, buffer);  
    }  
    //SendString(sock,"Cookie: mycookie=blablabla/r/n");  
    //  printf("Cookie: mycookie=blablabla/r/n");  
    SendString(sock,"Host: ");  
    strcat(headerSend, "Host: ");  
 
    SendString(sock,host);  
    strcat(headerSend, host);  
 
    SendString(sock,"/r/n");  
    strcat(headerSend, "/r/n");  
 
    if( (headerReceive!=NULL) && *headerReceive )  
    {  
        SendString(sock,headerReceive);  
        strcat(headerSend, headerReceive);  
    }  
 
    SendString(sock,"/r/n");                                // Send a blank line to signal end of HTTP headerReceive  
    strcat(headerSend, "/r/n");  
 
    if( (post!=NULL) && postLength )  
    {  
        send(sock,(const char*)post,postLength,0);  
        post[postLength]    = '/0';  
 
        strcat(headerSend, (const char*)post);  
    }  
 
    //strcpy(req->headerSend, headerSend);  
    req->headerSend     = (char*) malloc( sizeof(char*) * strlen(headerSend));  
    strcpy(req->headerSend, (char*) headerSend );  
 
 
    MemBufferCreate(&headersBuffer );  
    chars = 0;  
    done = FALSE;  
 
    while(!done)  
    {  
        l = recv(sock,buffer,1,0);  
        if(l<0)  
            done=TRUE;  
 
        switch(*buffer)  
        {  
        case '/r':  
            break;  
        case '/n':  
            if(chars==0)  
                done = TRUE;  
            chars=0;  
            break;  
        default:  
            chars++;  
            break;  
        }  
 
        MemBufferAddByte(&headersBuffer,*buffer);  
    }  
 
    req->headerReceive  = (char*) headersBuffer.buffer;  
    *(headersBuffer.position) = 0;  
 
 
 
    MemBufferCreate(&messageBuffer);                            // Now read the HTTP body  
 
    do 
    {  
        l = recv(sock,buffer,sizeof(buffer)-1,0);  
        if(l<0)  
            break;  
        *(buffer+l)=0;  
        MemBufferAddBuffer(&messageBuffer, (unsigned char*)&buffer, l);  
    } while(l>0);  
    *messageBuffer.position = 0;  
    req->message = (char*) messageBuffer.buffer;  
    req->messageLength = (messageBuffer.position - messageBuffer.buffer);  
 
 
    closesocket(sock);                                          // Cleanup  
 
    return 0;  
}  
 
 
//*******************************************************************************************************  
// SendRequest  
//  
//*******************************************************************************************************  
int Request::SendRequest(bool IsPost, string url, string& psHeaderSend, string& psHeaderReceive, string& psMessage)  
{  
    HTTPRequest         req;  
    int                 i,rtn;  
    LPSTR               buffer;  
 
    req.headerSend                          = NULL;  
    req.headerReceive                       = NULL;  
    req.message                             = NULL;  
 
    //Read in arguments  
 
 
    if(IsPost)  
    {                                                   /* POST */  
        i       = psHeaderSend.length();  
        buffer  = (char*) malloc(i+1);  
        strcpy(buffer, psHeaderSend.c_str());  
 
        rtn             = SendHTTP( url,  
            "Content-Type: application/x-www-form-urlencoded/r/n",  
            (unsigned char*)buffer,  
            i,  
            &req);  
 
        free(buffer);  
    }  
    else/* GET */ 
    {  
        rtn = SendHTTP(url,NULL,NULL,0,&req);  
    }  
 
 
 
    if(!rtn)                                            //Output message and/or headerSend   
    {  
        psHeaderSend        = req.headerSend;  
        psHeaderReceive     = req.headerReceive;  
        psMessage           = req.message;  
 
 
        free(req.headerSend);  
        free(req.headerReceive);  
        free(req.message);  
        return 1;  
    }  
    else 
    {  
        return 0;  
    }  
} 
 


原文链接:http://blog.csdn.net/favormm/article/details/5224506
加载中
返回顶部
顶部