linux下HttpGet、HttpPost的C++实现
来源:互联网 发布:如何加入淘宝直播 编辑:程序博客网 时间:2024/05/21 08:45
- #include "HttpRequest.h"
- int main()
- {
- HttpRequest* Http = new HttpRequest;
- char* str = (char*)malloc(BUFSIZE);
- memset(str, 0, BUFSIZE);
- if(Http->HttpGet("http://www.baidu.com", str)) {
- printf("%s\n", str);
- } else {
- printf("http://www.baidu.com HttpGet请求失败!\n");
- }
- memset(str, 0, BUFSIZE);
- //安装Tomcat
- if(Http->HttpGet("127.0.0.1", str)) {
- printf("%s\n", str);
- } else {
- printf("127.0.0.1 HttpGet请求失败!\n");
- }
- free(str);
- return 0;
- }
[cpp] view plain copy
- #ifndef __HTTP__
- #define __HTTP__
- #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;
- };
- #endif
[cpp] view plain copy
- #include "HttpRequest.h"
- HttpRequest::HttpRequest()
- {
- }
- HttpRequest::~HttpRequest()
- {
- }
- /**
- * 功能描述:HttpGet请求
- * 参数说明:
- * strUrl: Http请求URL
- * strResponse:Http请求响应
- * 返 回 值:
- * 1表示成功
- * 0表示失败
- **/
- 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, "%d", uLen);
- strcat(strHttpHead, "Content-Type: application/x-www-form-urlencoded\r\n");
- strcat(strHttpHead, "Content-Length: ");
- strcat(strHttpHead, len);
- strcat(strHttpHead, "\r\n\r\n");
- strcat(strHttpHead, strData);
- }
- strcat(strHttpHead, "\r\n\r\n");
- free(strHost);
- return strHttpHead;
- }
- //发送HTTP请求并接受响应
- char* HttpRequest::HttpDataTransmit(char *strHttpHead, const int iSockFd)
- {
- char* buf = (char*)malloc(BUFSIZE);
- memset(buf, 0, BUFSIZE);
- int ret = send(iSockFd,(void *)strHttpHead,strlen(strHttpHead)+1,0);
- free(strHttpHead);
- if (ret < 0) {
- DebugOut("%s %s %d\tsend error! Error code: %d,Error message: %s\n", __FILE__, __FUNCTION__, __LINE__, errno, strerror(errno));
- close(iSockFd);
- return NULL;
- }
- while(1)
- {
- ret = recv(iSockFd, (void *)buf, BUFSIZE,0);
- if (ret == 0) //连接关闭
- {
- close(iSockFd);
- return NULL;
- }
- else if(ret > 0) {
- return buf;
- }
- else if(ret < 0) //出错
- {
- if(errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) {
- continue;
- }
- else {
- close(iSockFd);
- return NULL;
- }
- }
- }
- }
- //从HTTP请求URL中获取主机地址,网址或者点分十进制IP地址
- char* HttpRequest::GetHostAddrFromUrl(const char* strUrl)
- {
- char url[URLSIZE] = {0};
- strcpy(url, strUrl);
- char* strAddr = strstr(url, "http://");//判断有没有http://
- if(strAddr == NULL) {
- strAddr = strstr(url, "https://");//判断有没有https://
- if(strAddr != NULL) {
- strAddr += 8;
- }
- } else {
- strAddr += 7;
- }
- if(strAddr == NULL) {
- strAddr = url;
- }
- int iLen = strlen(strAddr);
- char* strHostAddr = (char*)malloc(iLen+1);
- memset(strHostAddr, 0, iLen+1);
- for(int i=0; i<iLen+1; i++) {
- if(strAddr[i] == '/') {
- break;
- } else {
- strHostAddr[i] = strAddr[i];
- }
- }
- return strHostAddr;
- }
- //从HTTP请求URL中获取HTTP请参数
- char* HttpRequest::GetParamFromUrl(const char* strUrl)
- {
- char url[URLSIZE] = {0};
- strcpy(url, strUrl);
- char* strAddr = strstr(url, "http://");//判断有没有http://
- if(strAddr == NULL) {
- strAddr = strstr(url, "https://");//判断有没有https://
- if(strAddr != NULL) {
- strAddr += 8;
- }
- } else {
- strAddr += 7;
- }
- if(strAddr == NULL) {
- strAddr = url;
- }
- int iLen = strlen(strAddr);
- char* strParam = (char*)malloc(iLen+1);
- memset(strParam, 0, iLen+1);
- int iPos = -1;
- for(int i=0; i<iLen+1; i++) {
- if(strAddr[i] == '/') {
- iPos = i;
- break;
- }
- }
- if(iPos == -1) {
- strcpy(strParam, "");;
- } else {
- strcpy(strParam, strAddr+iPos+1);
- }
- return strParam;
- }
- //从HTTP请求URL中获取端口号
- int HttpRequest::GetPortFromUrl(const char* strUrl)
- {
- int iPort = -1;
- char* strHostAddr = GetHostAddrFromUrl(strUrl);
- if(strHostAddr == NULL) {
- return -1;
- }
- char strAddr[URLSIZE] = {0};
- strcpy(strAddr, strHostAddr);
- free(strHostAddr);
- char* strPort = strchr(strAddr, ':');
- if(strPort == NULL) {
- iPort = 80;
- } else {
- iPort = atoi(++strPort);
- }
- return iPort;
- }
- //从HTTP请求URL中获取IP地址
- char* HttpRequest::GetIPFromUrl(const char* strUrl)
- {
- char* strHostAddr = GetHostAddrFromUrl(strUrl);
- int iLen = strlen(strHostAddr);
- char* strAddr = (char*)malloc(iLen+1);
- memset(strAddr, 0, iLen+1);
- int iCount = 0;
- int iFlag = 0;
- for(int i=0; i<iLen+1; i++) {
- if(strHostAddr[i] == ':') {
- break;
- }
- strAddr[i] = strHostAddr[i];
- if(strHostAddr[i] == '.') {
- iCount++;
- continue;
- }
- if(iFlag == 1) {
- continue;
- }
- if((strHostAddr[i] >= '0') || (strHostAddr[i] <= '9')) {
- iFlag = 0;
- } else {
- iFlag = 1;
- }
- }
- free(strHostAddr);
- if(strlen(strAddr) <= 1) {
- return NULL;
- }
- //判断是否为点分十进制IP地址,否则通过域名地址获取IP地址
- if((iCount == 3) && (iFlag == 0)) {
- return strAddr;
- } else {
- struct hostent *he = gethostbyname(strAddr);
- free(strAddr);
- if (he == NULL) {
- return NULL;
- } else {
- struct in_addr** addr_list = (struct in_addr **)he->h_addr_list;
- for(int i = 0; addr_list[i] != NULL; i++) {
- return inet_ntoa(*addr_list[i]);
- }
- return NULL;
- }
- }
- }
- //检查SocketFd是否为可写不可读状态
- int HttpRequest::SocketFdCheck(const int iSockFd)
- {
- struct timeval timeout ;
- fd_set rset,wset;
- FD_ZERO(&rset);
- FD_ZERO(&wset);
- FD_SET(iSockFd, &rset);
- FD_SET(iSockFd, &wset);
- timeout.tv_sec = 3;
- timeout.tv_usec = 500;
- int iRet = select(iSockFd+1, &rset, &wset, NULL, &timeout);
- if(iRet > 0)
- {
- //判断SocketFd是否为可写不可读状态
- int iW = FD_ISSET(iSockFd,&wset);
- int iR = FD_ISSET(iSockFd,&rset);
- if(iW && !iR)
- {
- char error[4] = "";
- socklen_t len = sizeof(error);
- int ret = getsockopt(iSockFd,SOL_SOCKET,SO_ERROR,error,&len);
- if(ret == 0)
- {
- if(!strcmp(error, ""))
- {
- return iRet;//表示已经准备好的描述符数
- }
- else
- {
- DebugOut("%s %s %d\tgetsockopt error code:%d,error message:%s", __FILE__, __FUNCTION__, __LINE__, errno, strerror(errno));
- }
- }
- else
- {
- DebugOut("%s %s %d\tgetsockopt failed. error code:%d,error message:%s", __FILE__, __FUNCTION__, __LINE__, errno, strerror(errno));
- }
- }
- else
- {
- DebugOut("%s %s %d\tsockFd是否在可写字符集中:%d,是否在可读字符集中:%d\t(0表示不在)\n", __FILE__, __FUNCTION__, __LINE__, iW, iR);
- }
- }
- else if(iRet == 0)
- {
- return 0;//表示超时
- }
- else
- {
- return -1;//select出错,所有描述符集清0
- }
- return -2;//其他错误
- }
- //打印输出
- void HttpRequest::DebugOut(const char *fmt, ...)
- {
- #ifdef __DEBUG__
- va_list ap;
- va_start(ap, fmt);
- vprintf(fmt, ap);
- va_end(ap);
- #endif
- }
- int HttpRequest::m_iSocketFd = INVALID_SOCKET;
阅读全文
0 0
- linux下HttpGet、HttpPost的C++实现
- linux下HttpGet、HttpPost的C++实现
- java 实现 httppost 和 httpget
- okhttp实现 httpget 和 httppost 的java实现
- java最简单的方式实现httpget和httppost请求
- android的HttpGet和HttpPost
- HttpGet和HttpPost的区别
- HttpPost与HttpGet的区别
- HttpClite的HttpGet和HttpPost
- HttpGet HttpPost
- HTTPClient模块的HttpGet和HttpPost
- 使用httpPost和httpGet出现的bug
- HTTPClient模块的HttpGet和HttpPost
- HTTPClient模块的HttpGet和HttpPost .
- HTTPClient模块的HttpGet和HttpPost
- HttpPost 和Httpget 的简单应用
- 获取服务端的字符串 HttpGet、HttpPost
- HTTPClient模块的HttpGet和HttpPost
- linux网卡状态程序移植到android无法使用getifaddrs的问题
- 谈JavaScript的继承
- 创建JS问题
- XenStore 和 Xenbus
- C小加 之 随机数
- linux下HttpGet、HttpPost的C++实现
- Git常用命令
- CodeM美团点评编程大赛资格赛C题
- 「七天自制PHP框架」第三天:PHP实现的设计模式
- 日媒感慨中国手机发展,超乎日本人想象!
- 「七天自制PHP框架」第二天:模型与数据库
- 【软件外包】ITO与BPO
- js时间函数大全
- MTK Camera(OV13850) 驱动移植