纯C++实现的HTTP请求(POST/GET),支持windows和linux, 进行简单的封装, 方便调用。实现如下:
.h文件
#pragma once typedef size_t (*pfn_write_data)(char *buffer,size_t size, size_t nitems,void *pattach); //优点:不需要依赖第三方库,缺点:功能单一如:不支持301跳转 class CHttpConnect { public: CHttpConnect(); ~CHttpConnect(void); static string HttpPost(std::string host, std::string post); static string HttpGet(std::string host); static void HttpDownload(std::string host,pfn_write_data pwrite_data,void* pattach=NULL); private: static short ParseUrl(std::string& host,std::string& path); static string SocketHttp(std::string host, std::string request,short port,pfn_write_data pwrite_data=NULL,void* pattach=NULL); };
.cpp文件
#include "StdAfx.h" #include "HttpConnect.h" #include <WinSock.h> #include <stdio.h> #include <sstream> #include <iostream> #include <algorithm> #ifdef WIN32 #pragma comment(lib,"ws2_32.lib") #endif CHttpConnect::CHttpConnect() { } CHttpConnect::~CHttpConnect(void) { } short CHttpConnect::ParseUrl(std::string& host,std::string& path) { short nPort = 80; //处理主机域名不能带http开头 int pos = host.find("http://"); if (pos >= 0) { int endPos = host.find("/",pos + 7); if(endPos >= 0) { path = host.substr(endPos,host.length() - endPos); host = host.substr(pos + 7,endPos - pos - 7); } else { host = host.substr(pos + 7,host.length() - pos - 7); } pos = host.find(":"); if (pos >= 0) { string sPort = host.substr(pos + 1,host.length() - pos - 1); nPort = atoi(sPort.c_str()); host = host.substr(0,pos); } } else { int endPos = host.find("/"); if(endPos >= 0) { path = host.substr(endPos,host.length() - endPos); host = host.substr(0,endPos); } pos = host.find(":"); if (pos >= 0) { string sPort = host.substr(pos + 1,host.length() - pos - 1); nPort = atoi(sPort.c_str()); host = host.substr(0,pos); } } return nPort; } std::string CHttpConnect::SocketHttp(std::string host, std::string request,short port,pfn_write_data pwrite_data,void* pattach) { #ifdef WIN32 //此处一定要初始化一下,否则gethostbyname返回一直为空 WSADATA wsa = { 0 }; WSAStartup(MAKEWORD(2, 2), &wsa); #endif int sockfd; struct sockaddr_in address; struct hostent *server; sockfd = socket(AF_INET,SOCK_STREAM,0); address.sin_family = AF_INET; address.sin_port = htons(port); server = gethostbyname(host.c_str()); memcpy((char *)&address.sin_addr.s_addr,(char*)server->h_addr, server->h_length); if(-1 == connect(sockfd,(struct sockaddr *)&address,sizeof(address))){ ASSERT("连接失败"); return ""; } #ifdef WIN32 send(sockfd, request.c_str(),request.size(),0); #else write(sockfd,request.c_str(),request.size()); #endif char buf[1024]; int actual = -1; bool checkHttpHead = true; LPCSTR lpLine = NULL; std::stringstream out; #ifdef WIN32 while(actual = recv(sockfd, buf, 1024,0)) #else while(actual = read(sockfd, buf, 1024)) #endif { if (checkHttpHead) { if ((lpLine = strstr(buf,"\r\n\r\n"))) { int offset = lpLine - buf + strlen("\r\n\r\n");//出现的指针减去起始指针得到长度 if(pwrite_data == NULL) out << string(buf+offset,actual-offset) << endl;//数据写到缓存 else pwrite_data(buf+offset,1,actual-offset,pattach); checkHttpHead = false;//http头读取完毕 lpLine = NULL;//指针放空 } continue; } if(pwrite_data == NULL) out << string(buf,actual) << endl;//数据写到缓存 else pwrite_data(buf,1,actual,pattach); } #ifdef WIN32 closesocket(sockfd); //此处一定要初始化一下,否则gethostbyname返回一直为空 ::WSACleanup(); #else close(sockfd); #endif string str_result = out.str(); return str_result; } std::string CHttpConnect::HttpPost(std::string host, std::string post) { string path; short nPort = ParseUrl(host,path); //POST请求方式 std::stringstream stream; stream << "POST " << path; stream << " HTTP/1.0\r\n"; stream << "Host: "<< host << "\r\n"; stream << "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3\r\n"; stream << "Content-Type:application/x-www-form-urlencoded\r\n"; stream << "Content-Length:" << post.length()<<"\r\n"; stream << "Connection:close\r\n\r\n"; stream << post.c_str(); return SocketHttp(host, stream.str(),nPort); } std::string CHttpConnect::HttpGet(std::string host) { //GET请求方式 std::stringstream stream; string path; short nPort = ParseUrl(host,path); stream << "GET " << path; stream << " HTTP/1.0\r\n"; stream << "Host: " << host << "\r\n"; stream <<"User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3\r\n"; stream <<"Connection:close\r\n\r\n"; return SocketHttp(host, stream.str(),nPort); } void CHttpConnect::HttpDownload(std::string host,pfn_write_data pwrite_data,void* pattach) { //GET请求方式 std::stringstream stream; string path; short nPort = ParseUrl(host,path); stream << "GET " << path; stream << " HTTP/1.0\r\n"; stream << "Host: " << host << "\r\n"; stream <<"User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3\r\n"; stream <<"Connection:close\r\n\r\n"; SocketHttp(host, stream.str(),nPort,pwrite_data,pattach); }
调用方法:
收藏的用户(0) X
正在加载信息~
推荐阅读
最新回复 (0)
站点信息
- 文章2300
- 用户1336
- 访客10722748
每日一句
All things in their being are good for something.
天生我材必有用。
天生我材必有用。
新会员