简介:
个人项目中有时候需要用到百度提供的API服务,GET请求在其他高级语言中已经直接提供了,但在C语言中需要自行编写GET请求或者直接使用开源的包,对于网络编程还是比较熟悉了,但是在使用一些免费服务时需要GET请求,于是自己利用C/C++语言编写了一个简单的GET请求工具。
原理:
不管再该高级的语言实现的GET请求他都脱离不了基本的网络通信和HTTP协议,所以这里使用网络通信编程技术和HTTP协议来实现,项目中的例子我只在百度免费API上测试过,其他的都大同小异。
/*************************************************************************************************************************************************************************************/
/*
* Sockets.h
*
* Created on: 2016年9月20日
* Author: gavin
*/
#ifndef SOCKETS_H_
#define SOCKETS_H_
#include "string.h"
#include "string"
#include "stdio.h"
#include "stdlib.h"
#include "sys/types.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
using std::string;
class Sockets
{
public:
int Server(string ServerIp, int ServerPort); /*新建一个服务器*/
int Client(string ServerIp, int ServerPort); /*客户端链接到服务器*/
string Get(char *url,string Header,string urlParam);
string Post(string url);
int SendMessage(char * Message);
int RecvMessage(int socket, char *buff, int len);
virtual ~Sockets();
private:
string ServerIp; /*服务器IP地址*/
int ServerPort; /*服务器端口号*/
int ClientFd; /*客户端描述符*/
int ServerFd; /*服务器描述符*/
int CheckErrorCode(char *ReturnMessage);
};
#endif /* SOCKETS_H_ */
/*******************************************************************************************************************************************************************************/
上面这段代码是源代码的.H文件,主要描述了类的组成
/*
* Sockets.cpp
*
* Created on: 2016年9月20日
* Author: gavin
*/
#include "Sockets.h"
#if 0
/*这是一个网络链接类*/
char BaiDuErrorCode[20][3] =
{
{300101,"User's request is expired","用户请求过期"},
{300102,"User call overrun per day","用户日调用量超限"},
{300103,"Service call overrun per second","服务每秒调用量超限"},
{300104,"Service call overrun per day","服务日调用量超限"},
{300201,"URL cannot be resolved","url无法解析"},
{300202,"Missing apikey","请求缺少apikey,登录即可获取"},
{300203,"Apikey or secretkey is NULL","服务没有取到apikey或secretkey"},
{300204,"Apikey does not exist","apikey不存在"},
{300205,"Api does not exist","api不存在"},
{300206,"Api out of service","api已关闭服务"},
{300207,"Service overdue, please pay in time","余额不足,请充值"},
{300208,"User not verified","未通过实名验证"},
{300209,"Service provider response status error","服务商响应status非200"},
{300301,"Internal error","内部错误"},
{300302,"Sorry,The system is busy. Please try again late","系统繁忙稍候再试"},
{-1, "手机号错误","手机号错误"},
{-2, "appkey参数有误","appkey参数有误"},
{-3, "手机号列表过长"," 手机号列表过长"},
{0, "succeed","查询成功"}
};
#endif
int Sockets::Server(string ServerIp, int ServerPort)
{
}
int Sockets::Client(string ServerIp, int ServerPort)
{
int socketFd = 0;
struct sockaddr_in their_addr =
{ 0 };
memset(&their_addr, 0, sizeof(their_addr));
their_addr.sin_family = AF_INET;
their_addr.sin_port = htons(ServerPort);
their_addr.sin_addr.s_addr = inet_addr(ServerIp.data());
socketFd = socket(PF_INET, SOCK_STREAM, 0);
cout << "ServerIp:" << ServerIp << " Port:" << ServerPort << endl;
if (socketFd < 0)
{
cout << "create socket error" << endl;
exit(-1);
}
if (connect(socketFd, (struct sockaddr *) &their_addr, sizeof(their_addr))
< 0)
{
cout << "connect socket error" << endl;
exit(-1);
}
cout << "*****************ServerConnectOK*****************" << endl;
ClientFd = socketFd;
return socketFd;
}
string Sockets::Get(char * url, string Header, string urlParam)
{
struct hostent *host;
struct in_addr addr;
char newurl[128] =
{ 0 };
char getfile[128] =
{ 0 };
char GetMessage[4096] ={0};
char ReBuf[4096] = {0};
char *str1 = NULL;
char *str2 = NULL;
/*截取有效字段*/
str1 = strstr(url, "//");
if (str1 != NULL)
strcpy(newurl, str1 + 2);
else
strcpy(newurl, url);
str1 = strstr(newurl, "com");
if (str1 == NULL)
{
cout << "newurl no .com" << endl;
}
newurl[(str1 - newurl) + 3] = '\0';
/*截取有效字段*/
printf("%s\n", newurl);
//获取主机信息
host = gethostbyname(newurl); /*通过域名获取服务器的IP地址*/
if (host == NULL)
{
cout << "gethostbyname error" << endl;
}
/*获取求求的文件*/
str1 = strstr(url, "com");
if (str1 == NULL)
{
str1 = strstr(url, "COM");
if (str1 != NULL)
{
cout << "url error" << endl;
}
else
{
cout << "url error" << endl;
}
}
strcpy(getfile, str1 + 3);
addr.s_addr = *(unsigned long *) host->h_addr;
cout << "hostname:" << host->h_name << endl;
cout << "hostip:" << inet_ntoa(addr) << endl;
Client(inet_ntoa(addr), 80);
#if 1
memset(GetMessage,0,sizeof(GetMessage));
sprintf(GetMessage,
"GET %s?%s HTTP/1.1\r\n\
Host: %s\r\n\
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:18.0)\r\n\
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n\
Accept-Encoding: gzip, deflate\r\n\
Content-Type: application/x-www-form-urlencoded; charset=UTF-8 \r\n\
Apikey: %s \r\n\
Connection: close \r\n\
\r\n\
%s\r\n",
getfile, urlParam.data(), newurl, Header.data(), urlParam.data());
#endif
SendMessage(GetMessage);
RecvMessage(ClientFd,ReBuf,4096);
return ReBuf;
return 0;
}
string Sockets::Post(string url)
{
}
int Sockets::SendMessage(char * Message)
{
int ret = 0;
int len = strlen(Message);
cout<<"SendMessageLen:"<
上面是类的具体定义
下面这个是测试代码
//============================================================================
// Name : Sockets_test.cpp
// Author : xiegui
// Version :
// Copyright : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================
#include
#include "Sockets.h"
using namespace std;
int main() {
Sockets *sockets = new Sockets();
string rebacj = sockets->Get("http://apis.baidu.com/showapi_open_bus/txt_like/txt_like","4ba22baecaffaa517b2efdeacca5ad18","t1=%E8%BF%99%E6%98%AF%E6%B5%8B%E8%AF%95%E6%96%87%E6%9C%AC&t2=%E8%BF%99%E6%98%AF%E6%96%87%E6%9C%AC");
cout<
/*下面是输出信息*/
apis.baidu.com
hostname:apis.n.shifen.com
hostip:180.149.144.74
ServerIp:180.149.144.74 Port:80
*****************ServerConnectOK*****************
SendMessageLen:566
GET /showapi_open_bus/txt_like/txt_like?t1=%E8%BF%99%E6%98%AF%E6%B5%8B%E8%AF%95%E6%96%87%E6%9C%AC&t2=%E8%BF%99%E6%98%AF%E6%96%87%E6%9C%AC HTTP/1.1
Host: apis.baidu.com
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:18.0)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Apikey: 4ba22baecaffaa517b2efdeacca5ad18
Connection: close
t1=%E8%BF%99%E6%98%AF%E6%B5%8B%E8%AF%95%E6%96%87%E6%9C%AC&t2=%E8%BF%99%E6%98%AF%E6%96%87%E6%9C%AC
463
HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: apikey
Access-Control-Allow-Methods: GET,POST,OPTIONS
Access-Control-Allow-Origin: *
Content-Length: 105
Content-Type: application/json;charset=utf-8
Date: Wed, 28 Sep 2016 12:51:05 GMT
Proxy_paynum: -1
Proxy_trynum: -1
Server: nginx/1.7.10
Connection: close
{"showapi_res_code":0,"showapi_res_error":"","showapi_res_body":{"ret_code":0,"like":0.8164965809277261}}
IP地址解析:
http://apis.baidu.com/showapi_open_bus/txt_like/txt_like
通过一个函数识别出http://apis.baidu.com/这个的IP地址,后面的可以识别出你要求情的是哪个程序、比如这里就是文本相识度比较的程序(也可以说是内部端口),
后面
4ba22baecaffaa517b2efdeacca5ad18这个是apikey
最后面是你要请求的参数。