linux c++ 实现http的get()函数

使用linux c++实现了http的get请求
传入参数:传入参数是要请求的url
传出参数:请求到的网页
为了方便说明,这里假定url = "http://search.360buy.com/Search?keyword=ŮЬ&page=67&ev=";
std::string chttpget::run(std::string url)
{
      string page;
      int sockfd, ret, i, h;
      struct sockaddr_in servaddr;
      char str[4096],buf[BUFSIZE];
      socklen_t len;
      fd_set t_set1;
      fd_set mask;
      struct timeval   tv;
 
      if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) 
      {
           printf("创建网络连接失败,本线程即将终止---socket error!\n");
           exit(0);
      };
 
 
      bzero(&servaddr, sizeof(servaddr));
      servaddr.sin_family = AF_INET;
      servaddr.sin_port = htons(PORT);
      //将域名转为ip地址
      struct hostent *host = gethostbyname(search.360buy.com);
      
      char* ipstr = (char *)inet_ntoa(*(struct in_addr *)(host->h_addr));
      if (inet_pton(AF_INET, ipstr, &servaddr.sin_addr) <= 0 )
      {
               printf("创建网络连接失败,本线程即将终止--inet_pton error!\n");
               exit(0);
      };
      // 非阻塞connect
        int flags=fcntl(sockfd,F_GETFL,0);
        fcntl(sockfd,F_SETFL,flags|O_NONBLOCK);
         ret =   connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));    
        if (-1 == ret)
        {
           printf("与远端建立了连接\n");
         if(errno != EINPROGRESS)
        {
           perror("connect");
           close(sockfd);
        }
 
        FD_ZERO(&mask);
        FD_SET(sockfd,&mask);
        tv.tv_sec = 1;
        tv.tv_usec = 0;
      
        switch(select(sockfd+1,NULL,&mask,NULL,&tv))
        {
       
         case -1:
         close(sockfd);
         case 0:
         close(sockfd);
       
         default:
         int error=0;
         socklen_t len = sizeof(int);
         if(getsockopt(sockfd,SOL_SOCKET,SO_ERROR,&error,&len))
         {
              if(0 == error)
            {
            printf("has connect");
            }
         }
        }
        }else if(0==ret)
        {
         printf("has connect\n");
        }

      memset(str, 0, 4096);
        // http协议请求字符串,每一行的后面一定要加\n隔开     
         strcat(str,"GET  /Search?keyword=ŮЬ&page=68&ev=  HTTP/1.1\n");
         strcat(str, "Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, */* \n");
         strcat(str, "Accept-Language: zh-cn\n");
         strcat(str,"User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; (R1 1.6); .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)\n");
        strcat(str,"Host:search.360buy.com\n");
         strcat(str,"Connection: Keep-Alive");
         strcat(str, "\r\n\r\n");
  ret = write(sockfd,str,strlen(str));
 
   if (ret < 0) 
   {
              printf("发送失败!错误代码是%d,错误信息是'%s'\n",errno, strerror(errno));
              exit(0);
   }
   else
   {
        printf("消息发送成功,共发送了%d个字节!\n\n", ret);
   }

         FD_ZERO(&t_set1);
         FD_SET(sockfd, &t_set1);

         while(1)
         {
     //设置超时为1秒,如果1秒还没有反应直接返回
                    tv.tv_sec= 1;
                     tv.tv_usec= 0;
                     h= 0;
                     memset(buf, 0, sizeof(buf));
                     h= select(sockfd +1, &t_set1, NULL, NULL, &tv);
                     if (h == 0)
                     {
                     close(sockfd);
                           return page;
                     }
                     if (h < 0) {
                                 close(sockfd);
                                 printf("在读取数据报文时SELECT检测到异常,该异常导致线程终止!\n");
                                 return "";
                     };
                       if (h > 0){
                                 memset(buf, 0, sizeof(buf));
                                 
                                 i= read(sockfd, buf, sizeof(buf));
                                 
                                 if(i>0)
                                 {
                                 page = page + buf;
                                 
                                 }else
                                 {
                                 close(sockfd);
                                 return page;
                                 }
    
                     }
         }
         close(sockfd);
         return page;
}
这样就完成了一个http请求。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux C 程序中,我们可以使用 HTTP 协议来进行 GET 和 POST 请求。 GET 请求是用来从服务器获取数据的方法。在 Linux C 程序中,我们可以使用 socket 编程来发送 GET 请求。首先,我们需要使用 socket() 函数创建一个套接字,然后使用 connect() 函数连接服务器。接下来,我们可以使用 send() 函数将 GET 请求发送给服务器。GET 请求的格式通常是一个 HTTP 头部加上一个空行,例如: ``` GET /path/to/resource HTTP/1.1 Host: www.example.com [其他请求头部] ``` 在发送了 GET 请求之后,我们可以使用 recv() 函数来接收服务器的响应,并将其打印出来。然后,我们可以使用 close() 函数关闭套接字。 POST 请求是用来向服务器提交数据的方法。与 GET 请求不同,POST 请求需要在 HTTP 头部中指定要提交的数据的长度,并将数据作为请求的正文发送给服务器。在 Linux C 程序中,我们可以通过将数据放入缓冲区中,并使用 send() 函数将请求发送给服务器。POST 请求的格式通常是一个 HTTP 头部,后面是一个空行,再后面是要提交的数据,例如: ``` POST /path/to/resource HTTP/1.1 Host: www.example.com Content-Length: 数据长度 [其他请求头部] 要提交的数据 ``` 在发送了 POST 请求之后,我们同样可以使用 recv() 函数来接收服务器的响应,并将其打印出来。最后,我们使用 close() 函数关闭套接字。 总结来说,无论是 GET 还是 POST 请求,我们都需要使用 socket 编程来与服务器通信,并使用相应的格式发送请求。通过接收并处理服务器的响应,我们可以实现Linux C 程序中进行 HTTP GET 和 POST 请求的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值