LINUX C++实现简单的http get请求客户机

来源:互联网 发布:专业电气制图软件 编辑:程序博客网 时间:2024/04/28 12:42

我觉得我注释写的很清楚了。。g++ -o 编译即可  ubuntu 14.04


#ifndef __http__#define __http__/*TODO : 连接失败后的特殊处理*/#include <cstring>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <netdb.h>#include <string.h>#include <stdio.h>#include <sys/socket.h>#include <sys/types.h>#include <netinet/in.h>#include <arpa/inet.h>#include <unistd.h>#include <sys/time.h>#include <errno.h>#include <stdlib.h>#include <string.h>#include <stdlib.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/sendfile.h>#include <sys/wait.h>#include <error.h>#include <time.h>#include <iostream>using std::string;using std::endl;using std::cout;using std::cin;#define HTTP_KEEP_ALIVE "Keep-Alive"#define HTTP_GET        "GET"class http_request_header{protected:string method; /*GET OPTION HEAD POST PUT DELETE TRACE CONNECT*/  //就是方法,但是我现在只实现了GET方法string file;//目前只实现了GET方法,这里也就是  www.baidu.com/?abc 大概意思就是file = "?abc"string host;   /*这里是纯IP*///CRLFprivate:/*这里在初始化的时候定义了一些常量,以后的程序可能会改*/string version;   /*默认就是 HTTP1.1 */string connection; /*  默认是Keep-Alive*/string space;  //就是空格string CRLF;   //就是回车,换行符。public:void set_method(const string &method);void set_file(const string &file);void set_host(const string &host);void set_connection(const string &connection);http_request_header(); //初始化函数,也就是初始化private里东西string make();//根据当前的数据,生成一个header};class httpclient{private:void http_client_create(const string &host, const int port);//创建一个客户机,参数分别形如 "192.168.1.1"和80这样的两个参数。第一个是IP,第二个是端口号void http_close();//断开和服务器链接int http_recv(string &ret);//接受服务器返回数据(比如get请求有返回数据)//函数返回值为最后一次调用recv函数的返回值。//如果3秒没有接受到消息,则会自动退出int http_client_send(string msg);//根据当前的header设置,向服务器发送一个msg信息。(会自动根据设置,生成头)//返回值和send函数意义相同。public:int http_get(const string host_addr, const string file, const int port, string &ret);//向host_addr发送一个http请求,其中的参数是file,端口号port。  返回的字符串为ret//这个函数的返回值,-1为失败,并会在标准输出上输出错误信息。否则返回1。private:int socket_fd;//socket常用char rec_buff[1024];//接受数据的buffstring msg;//临时变量http_request_header hrh;//http请求的头部。}http;int main(){string str;//http.http_get("14.215.177.38", "", 80, str); //百度首页http.http_get("http://14.215.177.37","s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=2&tn=baiduhome_pg&wd=重庆邮电大学移通学院&oq=%25E7%25BD%2591%25E9%25A1%25B5get%25E8%25AF%25B7%25E6%25B1%2582&rsv_pq=a74bcb630000e36c&rsv_t=83fbonPcSyxgw2tYRSXZS6dODMw0Zwk9jrvpFdc9JtHJbUHgnkMjFL4B04rEF%2F10R42C&rqlang=cn&rsv_enter=1&rsv_sug3=3&rsv_sug1=2&rsv_sug7=100&sug=%25E9%2587%258D%25E5%25BA%2586%25E9%2582%25AE%25E7%2594%25B5%25E5%25A4%25A7%25E5%25AD%25A6%25E7%25A7%25BB%25E9%2580%259A%25E5%25AD%25A6%25E9%2599%25A2&rsv_n=1&bs=网页get请求",80,str);//百度的一个网页,我们通过get请求cout << str<<endl;FILE *fout = fopen("index.html", "w"); //输出网页,自己可以打开浏览fprintf(fout, "%s", str.c_str());return 0;}/*-------------------http_request_header begin-----------------------------*/void http_request_header::set_method(const string &method){this -> method = method;}void http_request_header::set_file(const string &file){this -> file = file;}void http_request_header::set_host(const string &host){this -> host = host;}void http_request_header::set_connection(const string &connection){this -> connection = connection;}http_request_header::http_request_header(){version = string("HTTP/1.1");CRLF = string("\r\n");space = string(" ");}string http_request_header::make(){string ret = method;if(method.compare(string("GET"))==0){ret += string(" /") + file + space + version + CRLF\       +  string("HOST:") + space + host + CRLF\       +  string("Connection:")  + space + connection + CRLF\       +  CRLF;}else{printf("error : is not the GET request!?\n");exit(0);}return ret;}/*-------------------http_request_header end-----------------------------*//*-----------------------------------------------------------------------*//*-----------------------------------------------------------------------*//*-----------------------------------------------------------------------*//*-----------------------------------------------------------------------*//*-----------------------------------------------------------------------*//*-----------------------httpclient start--------------------------------*/void httpclient::http_client_create(const string &host, const int port){//struct hostent *he = NULL;struct sockaddr_in server_addr;cout << host <<" " << port << endl;server_addr.sin_family = AF_INET;server_addr.sin_port = htons(port);server_addr.sin_addr.s_addr = inet_addr(host.c_str());//*((struct in_addr *)he -> h_addr);if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ){printf("error: creat socket error\n");exit(0);//return -1;}if (connect(socket_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1){printf("error: connect socket error\n");exit(0);//return -1;}}void httpclient::http_close(){close(socket_fd);}int httpclient::http_recv(string &ret){int recvnum = 0;ret = "";memset(rec_buff, 0, sizeof(rec_buff));while (recvnum = recv(socket_fd, rec_buff, sizeof(rec_buff), 0) > 0){ret += string(rec_buff);memset(rec_buff, 0, sizeof(rec_buff));}return recvnum;}int httpclient::http_client_send(string msg){msg = hrh.make() + msg;int flag = send(socket_fd, msg.c_str(), msg.size() ,0);if (flag < 0){printf("send socket error\n");}return flag;}int httpclient::http_get(const string host_addr, const string file, const int port, string &ret){string host;if(host_addr.size() == 0){printf("error: url's length error \n");return -1;}if (host_addr.find("http://", 0) == -1){printf("warnning ! the host_addr is not the http ?\n");host = host_addr;}else{host = host_addr.substr(7, host_addr.size() - 7);}http_client_create(host ,port);if(socket_fd < 0){printf("error : http_lient_create failed\n");return -1;}//make the http headerhrh.set_method(HTTP_GET);hrh.set_file(file);hrh.set_host(host);hrh.set_connection(HTTP_KEEP_ALIVE);msg="";if( http_client_send(msg) < 0){printf("error : http_client_send failed..\n");return -1;}struct timeval timeout = {3, 0};int flag = 0;setsockopt(socket_fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(struct timeval));flag= http_recv(ret);http_close();return 1;}/*-----------------------httpclient   end--------------------------------*/#endif


原创粉丝点击