C/C++实现百度API GET请求

简介:

个人项目中有时候需要用到百度提供的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
最后面是你要请求的参数。



你可能感兴趣的:(嵌入式)