纯C++的Socket访问Http封装类
1.项目中要使用c++++来访问Web服务器,从网上找了个C++的封装类,其中调用了MFC,在VC2005上用能用,但是移植到VC2003就出问题了,干脆修改成了纯C++的,不敢独享,share之。
2.以下是调用方法:
#include "stdafx.h"
#include <iostream>
#include <string>
#include "httprequest.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;
}
直接上代码了,blog附件上传貌似有点问题,
Request.h
//****************************************** 
//纯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.0rn"); 
    strcat(headerSend, " HTTP/1.0rn"); 
 
    SendString(sock,"Accept: p_w_picpath/gif, p_w_picpath/x-xbitmap,"
        " p_w_picpath/jpeg, p_w_picpath/pjpeg, application/vnd.ms-excel,"
        " application/msword, application/vnd.ms-powerpoint,"
        " */*rn"); 
    strcat(headerSend, "Accept: p_w_picpath/gif, p_w_picpath/x-xbitmap,"
        " p_w_picpath/jpeg, p_w_picpath/pjpeg, application/vnd.ms-excel,"
        " application/msword, application/vnd.ms-powerpoint,"
        " */*rn"); 
 
    SendString(sock,"Accept-Language: en-usrn"); 
    strcat(headerSend, "Accept-Language: en-usrn"); 
 
    SendString(sock,"Accept-Encoding: gzip, defaultrn"); 
    strcat(headerSend, "Accept-Encoding: gzip, defaultrn"); 
 
    SendString(sock,"User-Agent: Neeao/4.0rn"); 
    strcat(headerSend, "User-Agent: Neeao/4.0rn"); 
 
    if(postLength) 
    { 
        sprintf(buffer,"Content-Length: %ldrn",postLength); 
        SendString(sock,buffer); 
        strcat(headerSend, buffer); 
    } 
    //SendString(sock,"Cookie: mycookie=blablablarn"); 
    //  printf("Cookie: mycookie=blablablarn"); 
    SendString(sock,"Host: "); 
    strcat(headerSend, "Host: "); 
 
    SendString(sock,host); 
    strcat(headerSend, host); 
 
    SendString(sock,"rn"); 
    strcat(headerSend, "rn"); 
 
    if( (headerReceive!=NULL) && *headerReceive ) 
    { 
        SendString(sock,headerReceive); 
        strcat(headerSend, headerReceive); 
    } 
 
    SendString(sock,"rn");                                // Send a blank line to signal end of HTTP headerReceive 
    strcat(headerSend, "rn"); 
 
    if( (post!=NULL) && postLength ) 
    { 
        send(sock,(const char*)post,postLength,0); 
        post[postLength]    = ''; 
 
        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-urlencodedrn", 
            (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; 
    } 
}