首页 > 代码库 > Linux下C++实现http请求
Linux下C++实现http请求
main.cpp
#include HttpReq.h
#include <string.h>
int main(void)
{
HttpRequest* Http;
char http_return[4096] = {0};
char http_msg[4096] = {0};
strcpy(http_msg, "http://目标主机的IP和要发送的请求信息");
if(Http->HttpGet(http_msg, http_return)){
std::cout << http_return << std::endl;
}
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
下面是头文件,和cpp文件放到同一个文件夹
HttpReq.h
//
// Created by thinker on 7/6/16.
//
#ifndef PROJECT_HTTPREQ_H
#define PROJECT_HTTPREQ_H
#endif //PROJECT_HTTPREQ_H
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <netdb.h>
#include <stdarg.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#define BUFSIZE 41000
#define URLSIZE 1024
#define INVALID_SOCKET -1
#define __DEBUG__
class HttpRequest
{
public:
HttpRequest();
~HttpRequest();
void DebugOut(const char *fmt, ...);
int HttpGet(const char* strUrl, char* strResponse);
int HttpPost(const char* strUrl, const char* strData, char* strResponse);
private:
int HttpRequestExec(const char* strMethod, const char* strUrl, const char* strData, char* strResponse);
char* HttpHeadCreate(const char* strMethod, const char* strUrl, const char* strData);
char* HttpDataTransmit(char *strHttpHead, const int iSockFd);
int GetPortFromUrl(const char* strUrl);
char* GetIPFromUrl(const char* strUrl);
char* GetParamFromUrl(const char* strUrl);
char* GetHostAddrFromUrl(const char* strUrl);
int SocketFdCheck(const int iSockFd);
static int m_iSocketFd;
};
int HttpRequest::HttpGet(const char* strUrl, char* strResponse)
{
return HttpRequestExec("GET", strUrl, NULL, strResponse);
}
/**
* 功能描述:HttpPost请求
* 参数说明:
* strUrl: Http请求URL
* strData: POST请求发送的数据
* strResponse:Http请求响应
* 返 回 值:
* 1表示成功
* 0表示失败
**/
int HttpRequest::HttpPost(const char* strUrl, const char* strData, char* strResponse)
{
return HttpRequestExec("POST", strUrl, strData, strResponse);
}
//执行HTTP请求,GET或POST
int HttpRequest::HttpRequestExec(const char* strMethod, const char* strUrl, const char* strData, char* strResponse)
{
//判断URL是否有效
if((strUrl == NULL) || (0 == strcmp(strUrl, ""))) {
DebugOut("%s %s %d\tURL为空\n", __FILE__, __FUNCTION__, __LINE__);
return 0;
}
//限制URL长度
if(URLSIZE < strlen(strUrl)) {
DebugOut("%s %s %d\tURL的长度不能超过%d\n", __FILE__, __FUNCTION__, __LINE__, URLSIZE);
return 0;
}
//创建HTTP协议头
char* strHttpHead = HttpHeadCreate(strMethod, strUrl, strData);
//判断套接字m_iSocketFd是否有效,有效就直接发送数据
if(m_iSocketFd != INVALID_SOCKET) {
//检查SocketFd是否为可写不可读状态
if(SocketFdCheck(m_iSocketFd) > 0) {
char* strResult = HttpDataTransmit(strHttpHead, m_iSocketFd);
if(NULL != strResult) {
strcpy(strResponse, strResult);
return 1;
}
}
}
//Create socket
m_iSocketFd = INVALID_SOCKET;
m_iSocketFd = socket(AF_INET, SOCK_STREAM, 0);
if (m_iSocketFd < 0 ) {
DebugOut("%s %s %d\tsocket error! Error code: %d,Error message: %s\n", __FILE__, __FUNCTION__, __LINE__, errno, strerror(errno));
return 0;
}
//Bind address and port
int iPort = GetPortFromUrl(strUrl);
if(iPort < 0) {
DebugOut("%s %s %d\t从URL获取端口失败\n", __FILE__, __FUNCTION__, __LINE__);
return 0;
}
char* strIP = GetIPFromUrl(strUrl);
if(strIP == NULL) {
DebugOut("%s %s %d\t从URL获取IP地址失败\n", __FILE__, __FUNCTION__, __LINE__);
return 0;
}
struct sockaddr_in servaddr;
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(iPort);
if (inet_pton(AF_INET, strIP, &servaddr.sin_addr) <= 0 ) {
DebugOut("%s %s %d\tinet_pton error! Error code: %d,Error message: %s\n", __FILE__, __FUNCTION__, __LINE__, errno, strerror(errno));
close(m_iSocketFd);
m_iSocketFd = INVALID_SOCKET;
return 0;
}
//Set non-blocking
int flags = fcntl(m_iSocketFd, F_GETFL, 0);
if(fcntl(m_iSocketFd, F_SETFL, flags|O_NONBLOCK) == -1) {
close(m_iSocketFd);
m_iSocketFd = INVALID_SOCKET;
DebugOut("%s %s %d\tfcntl error! Error code: %d,Error message: %s\n", __FILE__, __FUNCTION__, __LINE__, errno, strerror(errno));
return 0;
}
//非阻塞方式连接
int iRet = connect(m_iSocketFd, (struct sockaddr *)&servaddr, sizeof(servaddr));
if(iRet == 0) {
char* strResult = HttpDataTransmit(strHttpHead, m_iSocketFd);
if(NULL != strResult) {
strcpy(strResponse, strResult);
free(strResult);
return 1;
} else {
close(m_iSocketFd);
m_iSocketFd = INVALID_SOCKET;
free(strResult);
return 0;
}
}
else if(iRet < 0) {
if(errno != EINPROGRESS) {
return 0;
}
}
iRet = SocketFdCheck(m_iSocketFd);
if(iRet > 0) {
char* strResult = HttpDataTransmit(strHttpHead, m_iSocketFd);
if(NULL == strResult) {
close(m_iSocketFd);
m_iSocketFd = INVALID_SOCKET;
return 0;
}
else {
strcpy(strResponse, strResult);
free(strResult);
return 1;
}
}
else {
close(m_iSocketFd);
m_iSocketFd = INVALID_SOCKET;
return 0;
}
return 1;
}
//构建HTTP消息头
char* HttpRequest::HttpHeadCreate(const char* strMethod, const char* strUrl, const char* strData)
{
char* strHost = GetHostAddrFromUrl(strUrl);
char* strParam = GetParamFromUrl(strUrl);
char* strHttpHead = (char*)malloc(BUFSIZE);
memset(strHttpHead, 0, BUFSIZE);
strcat(strHttpHead, strMethod);
strcat(strHttpHead, " /");
strcat(strHttpHead, strParam);
free(strParam);
strcat(strHttpHead, " HTTP/1.1\r\n");
strcat(strHttpHead, "Accept: */*\r\n");
strcat(strHttpHead, "Accept-Language: cn\r\n");
strcat(strHttpHead, "User-Agent: Mozilla/4.0\r\n");
strcat(strHttpHead, "Host: ");
strcat(strHttpHead, strHost);
strcat(strHttpHead, "\r\n");
strcat(strHttpHead, "Cache-Control: no-cache\r\n");
strcat(strHttpHead, "Connection: Keep-Alive\r\n");
if(0 == strcmp(strMethod, "POST"))
{
char len[8] = {0};
unsigned uLen = strlen(strData);
sprintf(len,