HTTP Post

// testHttp003.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

// webrequest.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <string>
#include <fstream>
#include <winsock2.h>
#include <stdio.h>
#pragma comment(lib, "WS2_32")
using namespace std;

namespace DEVWEB
{
    struct ACloseSkt
    {
        ACloseSkt(SOCKET h)
        {
            m_h = h;
        }
        ~ACloseSkt()
        {
            if(m_h)
                closesocket(m_h);
            m_h = 0;
        }
        SOCKET m_h;
    };
    struct RequestParam
    {
        bool            bPost;      //是否为POST请求
        const char*     pPostData;  //为POST数据,需要自已维护内存;
        unsigned int    uiPostLen;  //为POST数据长度,主要为了兼容可以上传二进制数据,一般请求就为pPostData字符串长度
        const char*     pReferer;   //请求的引用页面,就是来源页面
        const char*     pAttachHeader;//附加自定义头
        bool            bBlock;     //true=阻塞式连接,false=异步连接,*******注意:使用异步必须设置超时时间
        unsigned int    uiTimeout;  //异步超时 单位ms
        RequestParam(){
            memset(this,0, sizeof(RequestParam));
            bBlock = true; bPost = false;
        }
    };
    void GetRealIP(string& ip, string& retip)
    {
        retip = ip;
        unsigned long t = inet_addr((char*)(LPCSTR)ip.c_str());
        if (t == INADDR_NONE)
        {
            hostent* hostInfo = gethostbyname((char*)(LPCSTR)ip.c_str());
            if (hostInfo)
            {
                struct in_addr *addr;
                addr = (struct in_addr*)hostInfo->h_addr_list[0];
                if(addr!=NULL)
                {
                    retip = inet_ntoa(*addr);
                }
            }else{
                printf("GetRealIP can‘t parse domain %s\n",ip.c_str());
            }
        }
    }
    //////////////////////////////////////////////////////////////////////////
    //szURL 一个完整的URL仅HTTP,HTTPS不支持,可以包含GET参数,如index.php?username=test
    //response 为请求返回的结果,包含HTTP头信息
    //pRP为附加参数,完成更复杂的请求
    ///////////////////////////////////////////////////////////////////////////
    bool WebRequest( const char* szURL, std::string& response, RequestParam* pRP = 0)
    {
        if (!szURL )
			return false;
		WORD wVersionRequested;
		WSADATA wsaData;
		int vMMVersion=MAKEWORD(1,1);

		int res = WSAStartup(vMMVersion, &wsaData);
        SOCKET hSkt = socket(AF_INET,SOCK_STREAM,res);
        if (INVALID_SOCKET == hSkt){
			OutputDebugString("WebRequest socket create failed!\n");
			return false;
		}
        ACloseSkt askt(hSkt);
        //是否设置为异步
        if ( pRP && pRP->bBlock == false)
        {
            ULONG nMode = 1;
            ioctlsocket( hSkt,FIONBIO,&nMode);
        }
        string strURL(szURL),host,ip,requrl;
        unsigned int nport = 80;
        if ( stricmp(string(strURL.substr(0,7)).c_str(), "http://") )
        {
            OutputDebugString("WebRequest parse url error, need http://\n");
            return false;
        }else{  //parse url;
            size_t nMH = strURL.find(‘:‘,8);
            size_t nPre =strURL.find(‘/‘,8);
            if ( nMH == -1 && nPre == -1)
            {
                host    = strURL.substr(7);
                requrl  = "/";
            }else if ( nPre != -1){
                if ( nMH != -1 && nPre > nMH){
                    host = strURL.substr(7,nMH-7);
                    nport = atoi( string(strURL.substr(nMH+1, nPre-1-nMH)).c_str());
                }else{
                    host = strURL.substr(7,nPre-7);
                }
                requrl = strURL.substr(nPre);
            }else if (nMH != -1){
                host = strURL.substr(7, nMH-7);
                nport= atoi( string(strURL.substr(nMH+1)).c_str());
                requrl = "/";
            }
        }
        GetRealIP(host,ip);
        sockaddr_in addr;
        addr.sin_addr.S_un.S_addr = inet_addr( ip.c_str() );
        addr.sin_port = htons(nport);
        addr.sin_family = AF_INET;
        if (pRP && pRP->bBlock)
        {
            if (SOCKET_ERROR == connect( hSkt, (sockaddr*)&addr,sizeof(addr)))
            {
                OutputDebugString("WebRequest connect server failed!\n");
                return false;
            }
        }else{
            if (SOCKET_ERROR == connect( hSkt, (sockaddr*)&addr, sizeof(addr)))
            {
                if ( WSAGetLastError() == 10035 )
                {
                    //connectioning
                }else{
                    OutputDebugString("WebRequest connect server failed!\n");
                    return false;
                }
            }
            DWORD dwTick = GetTickCount();
            do{
                fd_set    Set,WSet;
                FD_ZERO(&Set);
                FD_ZERO(&WSet);
                FD_SET(hSkt,&Set);
                FD_SET(hSkt,&WSet);
                timeval time;
                time.tv_sec = 0;
                time.tv_usec = 0;
                int nS = select(0, &Set, &WSet, NULL, &time);
                if( nS == SOCKET_ERROR )
                {
                    OutputDebugString("WebRequest connect server failed!(SELECT)\n");
                    return false;
                }else if(nS){
                    break;//connect sucess.
                }else{
                    if ( (GetTickCount() - dwTick) > pRP->uiTimeout )
                    {
                        //timeout
                        OutputDebugString("WebRequest connect server timeout!(SELECT)\n");
                        return false;
                    }
                }
            }while(true);
        }
        //fill header;
        string header;
        bool bSendBin = false;
        if (pRP)
        {
            header.append( pRP->bPost ? "POST " : "GET ");
            header.append(requrl);
            header.append(" HTTP/1.1\r\n");
            header.append("host:");
            header.append(host);
            header.append("\r\nUser-Agent:Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)\r\n");
            header.append("Content-Type:application/x-www-form-urlencoded\r\n");
            header.append("Accept:text/html,application/xhtml+xml,*/*\r\nConnection:close\r\n");
            char szCSize[50];
            sprintf(szCSize,"Content-Length:%d\r\n\r\n",pRP->uiPostLen);
            header.append(szCSize);
            if (pRP->pPostData){
                if ( strlen(pRP->pPostData) <= pRP->uiPostLen){
                    bSendBin = true;
                }else{
                    header.append(pRP->pPostData);
                }
            }
        }else{
            header.append("GET ");
            header.append(requrl);
            header.append(" HTTP/1.1\r\n");
            header.append("host:");
            header.append(host);
            header.append("\r\nUser-Agent:Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)\r\n");
            header.append("Content-Type:application/x-www-form-urlencoded\r\n");
            header.append("Accept:text/html,application/xhtml+xml,*/*\r\nConnection:close\r\n\r\n");
        }
        size_t headerlen = header.size();
        size_t nSendLen = 0;
        const char* pdata = header.c_str();
        DWORD dwTick = GetTickCount();
        do
        {
            int n = send(hSkt, pdata + nSendLen, int(headerlen - nSendLen),0);
            if( n == SOCKET_ERROR ){
                if ( 10035 == WSAGetLastError())
                {
                    //wait for send.
                    if (pRP && GetTickCount() - dwTick >= pRP->uiTimeout)
                    {
                        OutputDebugString("WebRequest send failed!\n");
                        return false;
                    }
                    Sleep(10);
                }else{
                    OutputDebugString("WebRequest send failed!\n");
                    return false;
                }
            }else if( n==0)
            {
                OutputDebugString("WebRequest send failed!\n");
                return false;
                break;
            }else{
                dwTick = GetTickCount();
                nSendLen += n;
            }
        } while (nSendLen < headerlen );
        if(bSendBin && pRP && pRP->pPostData && pRP->uiPostLen)
        {
            nSendLen = 0;
            pdata = (const char*) pRP->pPostData;
            dwTick = GetTickCount();
            do
            {
                int n = send(hSkt, pdata + nSendLen, pRP->uiPostLen - nSendLen,0);
                if( n == SOCKET_ERROR ){
                    if ( 10035 == WSAGetLastError())
                    {
                        //wait for send.
                        if (pRP && GetTickCount() - dwTick >= pRP->uiTimeout)
                        {
                            OutputDebugString("WebRequest send timeout!\n");
                            return false;
                        }
                        Sleep(10);
                    }else{
                        OutputDebugString("WebRequest send failed!\n");
                        return false;
                    }
                }else if( n==0)
                {
                    OutputDebugString("WebRequest send failed!\n");
                    return false;
                    break;
                }else{
                    dwTick = GetTickCount();
                    nSendLen += n;
                }
            } while (nSendLen < pRP->uiPostLen );
        }
        //recv response
        char    buf[2049];
        string& request = response;
        request.clear();
        dwTick = GetTickCount();
        do
        {
            int n = recv(hSkt, buf,2048,0);
            if ( n == SOCKET_ERROR )
            {
                if ( 10035 != WSAGetLastError() )
                {
                    OutputDebugString("DevWebService recv failed!\n");
                    return 0;
                    break;
                }else{
                    if (pRP && GetTickCount() - dwTick >= pRP->uiTimeout){
                        OutputDebugString("WebRequest recv timeout!\n");
                        return false;
                    }
                    Sleep(10);
                }
            }else if( n == 0 ){
                //host close recv finish
                OutputDebugString("WebRequest Recv FINISHED!\n");
                break;
            }else{
                buf[n] = ‘\0‘;
                request.append(buf);    dwTick = GetTickCount();
            }
        } while (true);
        return true;
    }
	string GetHtml(string response)
	{
		int conn_index=response.find("Connection:");
		string str=response.substr(conn_index);
		int line_index=str.find("\r\n");
		if(line_index!=-1)
		{
			string contect=str.substr(line_index);
			//MessageBox(NULL,contect.c_str(),"ok",0);
			return contect;
		}
		return str;
	}
}
//UTF8编码
std::string utf2ansi(LPCSTR pszSrc)
{
	int nSize = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)pszSrc, -1, 0, 0);
	if(nSize <= 0) return NULL;
	WCHAR *pwsz = new WCHAR[nSize+1];
	if( NULL == pwsz) return NULL;
	MultiByteToWideChar(CP_UTF8, 0,(LPCSTR)pszSrc, nSize, pwsz, nSize);
	pwsz[nSize] = 0;
	char *psz = new char[nSize+1];
	WideCharToMultiByte(CP_ACP, 0, pwsz, nSize, psz, nSize, NULL, NULL);
	string str = psz;
	delete pwsz;
	delete psz;
	return str;
}

int WideToUTF8(const std::string& _src,string fileName)
{
	int nBufSize = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)_src.c_str(),-1, NULL, 0, 0, FALSE);
	char *szBuf = new char[nBufSize];
	WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)_src.c_str(),-1, szBuf, nBufSize, 0, FALSE);
	ofstream fout(fileName.c_str(),std::ios::out);//std::ios::binary
	fout.write(szBuf,nBufSize);
	fout.close();
	//std::string strRet(szBuf);
	//delete []szBuf;
	//szBuf = NULL;
	/** 写出宽字符串时这样用,内容在text中
	if(fopen_s( &pFile, "log.txt","a")!=0)
	{
		std::string str = WideToUTF8( text );
		fputs(str.c_str(), pFile);
		fputc(‘\n‘,pFile);
		fclose(pFile);
	}*/
	return 0;
}

int writeToTxt(string fileName,string data)
{
	ofstream fout(fileName.c_str(),std::ios::out);//std::ios::binary
	//0xef, 0xbb, 0xbf,
	//fout.write((char*)0x00ef,4);
	//fout.write((char*)0x00bb,4);
	//fout.write((char*)0x00bf,4);
	//unsigned char uniTxt[] = {0xFF, 0xFE};          // Unicode file header
	//unsigned char endianTxt[] = {0xFE, 0xFF};       // Unicode big endian file header
	//unsigned char utf8Txt[] = {0xEF, 0xBB, 0xBF};   // UTF_8 file header
	fout<<0xEF<<0xBB<<0xBF<<endl;
	fout.write(data.c_str(),data.length());
	fout.close();
	return 0;
}
int writeToTxt002(string fileName,string data)
{
	FILE *file;
	file=fopen(fileName.c_str(),"rw");
	if(file==NULL)
	{
		printf("打开失败!\n");
		return -1;
	}
	fwrite(data.c_str(),data.length(),1,file);
	fclose(file);
	return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
	string rs;
	char post[80];
	sprintf(post,"username=xj&userpassword=123456");
	DEVWEB::RequestParam rp;
	rp.bPost = false;
	rp.pPostData = post;
	rp.uiPostLen = strlen(post);
	if ( DEVWEB::WebRequest( "http://www.baidu.com", rs,&rp))
	{
		rs=utf2ansi(rs.c_str());
		MessageBox(NULL,rs.c_str(),"ok",0);
		string html=DEVWEB::GetHtml(rs);
		MessageBox(NULL,html.c_str(),"ok",0);
		writeToTxt("test.html",html);

	}else{
		MessageBox(NULL,"错误","ok",0);
	}
	getchar();
	return 0;
}
时间: 2024-10-07 11:00:16