纯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)
站点信息
- 文章2315
- 用户1336
- 访客11840905
每日一句
Winter always arrives quietly, yet the chill comes suddenly.
冬天总是悄然来临,而寒意却骤然而至。
冬天总是悄然来临,而寒意却骤然而至。