C++实现文本消息推送--通过post请求方式访问第三方服务器从电脑向手机进行消息推送


 上半年在做人脸识别时需要将人脸识别的结果实时发送到手机上,就在网上找推送相关的东西,最后就决定尝试使用智游推送提供的推送功能,它当时是免费的。虽然我用的那个阶段有的时候还不怎么稳定~~。不知现在怎么样了。


 网上有很多免费的推送软件,都是第三方服务器提供的。应用较为广泛也有很多,如个推,极光推送,百度云推送,华为推送等等。我不是很了解,但是只要他们提供http协议接口就应该是同样的实现方法。


 我最终的目的就是:在电脑上进行人脸识别的时候会返回一个识别结果,是一串字符如“number 3- wxk”,我想将这串字符实时发送到手机上,在手机上能看见这串字符就可以了。模型如下图所示。听似很简单,但我java是完全不懂的,http协议也只是停留在听过概念的程度上,而人脸识别当然是用OPencvC++MFC做的,怎么推送呢,开始时真的完全是懵的。像我这种只想应用不用知道怎么开发的怎么入手呢?




 我询问了当时智游推送群里的技术,他们却不擅长C++,但是也给我很有用的提示,说他们的推送服务器是提供标准的http协议接口的,任何语言都可以去访问这个接口,但是只支持post方式的请求。


 于是去查了查,post方式的请求其实也是请求网页的一种方式,我们平时浏览网页的方式是另一种http请求方式---get请求方式。两者的主要区别是:get是从服务器获取数据,Post是向服务器发送数据;get传输的数据量小,post传输的数据量大;还有其他一些请求格式不一样的地方等。有很多资料在说两者的区别,以及实现方法,针对智游推送又怎么实现呢?



一.需要事先准备的工作有:


         1.去智游官网上注册账号,每个账号会得到一个独特的appkey,然后去“在线文档”找“三分钟快速集成”文档,按照文档在线操作,它会把我的账号和appkey集成进去,生成可用的Demo资源即可用的SDK,提示我下载下来,我下载到自己的电脑上。


        2.接下来开始给自己的电脑安装JavaAndroid开发环境。安装JavaJDK,配置环境变量,安装Eclipse,安装Android SDK。配置好。这个环境的搭建网上有很多详细的资料可以参考,需要的是耐心和细心。


 3.根据提供的“三分钟快速集成”文档,生成可用的APK包,此包传到手机上,安装成功即可。在手机上就出现推送的软件界面。可以将配置好的安装包安装到多部手机上同时推送。电脑进行推送之前,要进行保证电脑和手机都连接网络。


         4.做好这些之后准备工作就做完了,以上步骤都是跟着说明一步一步做好就行了的。就剩编程序从电脑去请求智游推送服务器的http接口了。手机将软件打开等着接收信息就可以了。


二.编程准备过程


        1.了解post请求方式。请求的格式分为:请求行;请求头部;空行;请求数据。这几个部分中


          (1)请求行组成:

              a.请求方法字段(例如:POST;

                                b.URL字段(例如智游推送提供的接口网址:http://dev.zypush.com/push/api/v3/sendmsg_ver03;

                                c.HTTP协议版本字段(例如:HTTP/1.1)。

              这三个部分之间用空格分隔。


          (2)请求头部组成:请求头部由关键字/值对组成,每行一对,关键字和值用英文冒号“:”分隔;


                 如:Host:dev.zypush.com


                     Connection:Keep-Alive


                     Content-Length:strlen(parameters)


                     Cache-Control:max-age=0


                     Content-Type:application/x-www-form-urlencoded


                     Accept:*/*


                     Accept-Encoding:gzip,deflate,sdch


                     Accept-Language: zh-CN,zh;q=0.8


                     还可以设置其他的信息。也可以减少设置的信息


        (3)空行:请求头最后一个参数之后必须有一个空行,发送回车符和换行符,通知服务器以下不再有请求头。


        (4)请求数据:需要客户填写表单。表单是有智游推送提供的各种参数设置接口。智游推送的接口参考表单参考“在线文档”REST APIPUSH API-v3”。如:


C++实现文本消息推送--通过post请求方式访问第三方服务器从电脑向手机进行消息推送_第1张图片

C++实现文本消息推送--通过post请求方式访问第三方服务器从电脑向手机进行消息推送_第2张图片


          2.了解推送的过程:

        (1)建立socket连接,端口设置为80

        (2)填写上述post请求的四个部分具体信息;

        (3)用send()函数向一个已经连接的socket发送数据;

        (4)关闭socket连接。


三.消息推送程序示例代码如下所示:

#include "stdafx.h" 
#include <afxwin.h> // MFC core and standard components 
#include <iostream>
#include <string>
#include <winsock2.h>
using namespace std;
//函数声明
int request(char* hostname, char* api, char* parameters);

//方法调用

int main(int argc, TCHAR* argv[], TCHAR* envp[])
{
	int nRetCode = 0;

	//initialize MFC and print and error on failure
	if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
	{
		_tprintf(_T("Fatal Error: MFC initialization failed\n"));
		return 1;
	}
	char parameter[1024] = {0};
	strcat(parameter, "userName=***");//填自己注册的账号
	strcat(parameter, "&appKey=****");//填自己的appkey
	strcat(parameter, "&receiveType=1");
	strcat(parameter, "&receiveUsers=3");
	strcat(parameter, "&msgType=1");
	strcat(parameter, "&msgTitle={\"haha\"}");
	strcat(parameter, "&msgTitle=haha");
	strcat(parameter, "&msgContent=haha");
	strcat(parameter, "&clientPlatform=android");
	request("dev.zypush.com", "http://dev.zypush.com/push/api/v3/sendmsg_ver03", parameter);
	return nRetCode;
}

//函数实现
int request(char* hostname, char* api, char* parameters)
{
	//建立socket连接
	WSADATA WsaData;//WSADATA结构被用来储存调用AfxSocketInit全局函数返回的Windows Sockets初始化信息。
	WSAStartup(0x0101, &WsaData);//使用Winsock库函数之前,必须先调用函数WSAStartup,该函数负责初始化动态连接库Ws2_32.dll

	//初始化socket
	struct hostent* host_addr = gethostbyname(hostname);//gethostbyname()返回对应于给定主机名的包含主机名字和地址信息的hostent结构指针。
	if (host_addr == NULL)
	{
		cout<<"Unable to locate host"<<endl;
		return -103;
	}
	sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons((unsigned short)80);
	sin.sin_addr.s_addr = *((int*)*host_addr->h_addr_list);
	int sock = socket(AF_INET, SOCK_STREAM, 0);
	if (sock == -1)
	{
		return -100;
	}

	//建立连接
	if (connect(sock, (const struct sockaddr *)&sin, sizeof(sockaddr_in) ) == -1) //建立socket连线,对于流类套接口(SOCK_STREAM类型),利用名字来与一个远程主机建立连接,一旦套接口调用成功返回,它就能收发数据了
	{
		cout<<"connect failed"<<endl;
		return -101;
	}
	//初始化发送信息
	char send_str[2048] = {0};
	//头信息
	strcat(send_str, "POST ");
	strcat(send_str, api);
	strcat(send_str, " HTTP/1.1\r\n"); //\r换行相当于回车/ \n新行

	strcat(send_str, "Host: ");
	strcat(send_str, hostname);
	strcat(send_str, "\r\n");
	strcat(send_str, "Connection: Keep-Alive\r\n");

	char content_header[100];
	sprintf(content_header,"Content-Length: %d\r\n", strlen(parameters));

	strcat(send_str, content_header);
	strcat(send_str, "Cache-Control: max-age=0\r\n");
	strcat(send_str, "Content-Type: application/x-www-form-urlencoded\r\n");
	strcat(send_str, "Accept: */*\r\n");
	strcat(send_str, "Accept-Encoding: gzip,deflate,sdch\r\n");
	strcat(send_str, "Accept-Language: zh-CN,zh;q=0.8\r\n");


	//内容信息或者是参数信息
	strcat(send_str, "\r\n");
	strcat(send_str, parameters);
	if (send(sock, send_str, strlen(send_str),0) == -1) //向一个已连接的套接口发送数据。int PASCAL FAR send( SOCKET s, const char FAR* buf, int len, int flags);s:一个用于标识已连接套接口的描述字。buf:包含待发送数据的缓冲区。len:缓冲区中数据的长度。flags:调用执行方式。
	{
		//发送失败就要显示发送失败
		cout<<"send failed"<<endl;
		return -101;
	}
	else
	{
		//发送成功就要显示发送的内容
		cout<<send_str<<"\r\n\r\n"<<endl;
	}
	//获取返回信息
	char recv_str[4096] = {0};
	if (recv(sock, recv_str, sizeof(recv_str), 0) == -1)
	{
		cout<<"recv failed"<<endl;//从一个套接口接收数据。s:一个标识已连接套接口的描述字。buf:用于接收数据的缓冲区。len:缓冲区长度。flags:指定调用方式。
		return -101;
	}
	//打印发送的信息
	cout<<recv_str<<endl;
	//关闭socket连接
	WSACleanup( );
	//暂停显示
	system("pause");
	return 0;
}





四.结果。

     当把这个程序添加到我自己的人脸识别程序中后,手机端接收的信息如下图所示:




你可能感兴趣的:(C++实现文本消息推送--通过post请求方式访问第三方服务器从电脑向手机进行消息推送)