linux下HttpGet、HttpPost的C++实现
程序员文章站
2023-08-26 09:29:00
#include "httprequest.h"
int main()
{
httprequest* http = new httprequest;
ch...
#include "httprequest.h"
int main() { httprequest* http = new httprequest; char* str = (char*)malloc(bufsize); memset(str, 0, bufsize); if(http->httpget("https://www.baidu.com", str)) { printf("%s\n", str); } else { printf("https://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; }
#ifndef __http__ #define __http__ #include #include #include #include #include #include #include #include #include #include #include #include #include #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
#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, "https://");//判断有没有https:// 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="" strurl)="" char="" url[urlsize]="{0};" strcpy(url,="" strurl);="" straddr="strstr(url," "http:="" ");="" 判断有没有http:="" if(straddr="=" null)="" "https:="" 判断有没有https:="" !="null)" +="8;" int="" ilen="strlen(straddr);" strparam="(char*)malloc(ilen+1);" memset(strparam,="" 0,="" ilen+1);="" ipos="-1;" for(int="" i="0;" )="" ||="" (strhostaddr[i]="" <="9" ))="" iflag="0;" free(strhostaddr);="" if(strlen(straddr)="" null;="" 判断是否为点分十进制ip地址,否则通过域名地址获取ip地址="" if((icount="=" 3)="" &&="" (iflag="=" 0))="" straddr;="" struct="" hostent="" *he="gethostbyname(straddr);" free(straddr);="" if="" (he="=" in_addr**="" addr_list="(struct" in_addr="" **)he->h_addr_list;="" addr_list[i]="" inet_ntoa(*addr_list[i]);="" 检查socketfd是否为可写不可读状态="" httprequest::socketfdcheck(const="" isockfd)="" timeval="" timeout="" ;="" fd_set="" rset,wset;="" fd_zero(&rset);="" fd_zero(&wset);="" fd_set(isockfd,="" &rset);="" &wset);="" timeout.tv_sec="3;" timeout.tv_usec="500;" iret="select(isockfd+1," &rset,="" &wset,="" null,="" &timeout);="" if(iret="" >="" 0)="" 判断socketfd是否为可写不可读状态="" iw="fd_isset(isockfd,&wset);" ir="fd_isset(isockfd,&rset);" if(iw="" !ir)="" error[4]="" socklen_t="" len="sizeof(error);" ret="getsockopt(isockfd,sol_socket,so_error,error,&len);" if(ret="=" if(!strcmp(error,="" ""))="" iret;="" 表示已经准备好的描述符数="" debugout("%s="" %s="" %d\tgetsockopt="" error="" code:%d,error="" message:%s",="" __file__,="" __function__,="" __line__,="" errno,="" strerror(errno));="" failed.="" %d\tsockfd是否在可写字符集中:%d,是否在可读字符集中:%d\t(0表示不在)\n",="" iw,="" ir);="" 0;="" 表示超时="" -1;="" select出错,所有描述符集清0="" -2;="" 其他错误="" 打印输出="" void="" httprequest::debugout(const="" *fmt,="" ...)="" #ifdef="" __debug__="" va_list="" ap;="" va_start(ap,="" fmt);="" vprintf(fmt,="" ap);="" va_end(ap);="" #endif="" httprequest::m_isocketfd="invalid_socket;" <="" pre=""> <p> </p><p> </p></ilen+1;>
上一篇: 杨梅的功效与作用你知道多少?