C++服务器的push推送通知的代码,SSL链接
来源:互联网 发布:合肥唯米淘宝培训 编辑:程序博客网 时间:2024/05/01 04:07
- #ifndef SSLCOMM_H
- #define SSLCOMM_H
- #ifdef linux
- #include <assert.h>
- #include "openssl/pem.h"
- #include "openssl/rsa.h"
- #include "openssl/crypto.h"
- #include "openssl/x509.h"
- #include "openssl/ssl.h"
- #include "openssl/err.h"
- #include "openssl/rand.h"
- #include "errno.h"
- #include "sys/socket.h"
- #include "netinet/in.h"
- #include "unistd.h"
- #include <arpa/inet.h>
- #include <netdb.h>
- #include "Utility.h"
- #define APNS_DEV
- #if defined(APNS_DEV)
- #define CA_CERT_PATH "./pem"
- #define RSA_CLIENT_CERT "./pem/a.pem"
- #define RSA_CLIENT_KEY "./pem/a.pem"
- /* Development Connection Infos */
- #define APPLE_HOST "gateway.sandbox.push.apple.com"
- #define APPLE_PORT 2195
- #define APPLE_FEEDBACK_HOST "feedback.sandbox.push.apple.com"
- #define APPLE_FEEDBACK_PORT 2196
- #else
- #define CA_CERT_PATH "./pem"
- #define RSA_CLIENT_CERT "./pem/b.pem"
- #define RSA_CLIENT_KEY "./pem/b.pem"
- #define APPLE_HOST "gateway.push.apple.com"
- #define APPLE_PORT 2195
- #define APPLE_FEEDBACK_HOST "feedback.push.apple.com"
- #define APPLE_FEEDBACK_PORT 2196
- #endif
- class CSSLComm
- {
- public:
- CSSLComm();
- ~CSSLComm();
- bool connected();
- bool ssl_connect(const char *host, int port, const char *certfile, const char *keyfile, const char* capath);
- void PushNotification(const char *pToken,const char *pMsg);
- void GenPushData(const char *pToken);
- int GenPayloadData(int badgeNum,const char *pMsg = NULL);
- private:
- void Reset();
- private:
- SSL_CTX *m_pctx;
- SSL *m_pssl;
- const SSL_METHOD *m_pmeth;
- X509 *m_pserver_cert;
- EVP_PKEY *m_pkey;
- /* Socket Communications */
- struct sockaddr_in m_server_addr;
- struct hostent *m_phost_info;
- int m_sockfd;
- uint16 m_tokenLen;
- struct PUSHDATA
- {
- char szToken[1+2+32];
- char szPayload[2+256];
- }m_data;
- CSyncCritical m_lock;
- };
- #endif
- #endif // SSLCOMM_H
//SSLComm.cpp
- #ifdef linux
- #include "SSLComm.h"
- CSSLComm::CSSLComm()
- {
- //ctor
- m_sockfd = -1;
- m_pctx = NULL;
- m_pssl = NULL;
- m_pmeth = NULL;
- m_pserver_cert = NULL;
- m_pkey = NULL;
- m_tokenLen = htons(32);
- memset((void*)&m_data,0,sizeof(m_data));
- }
- CSSLComm::~CSSLComm()
- {
- //dtor
- Reset();
- }
- void CSSLComm::Reset()
- {
- if(m_pssl)
- {
- SSL_shutdown(m_pssl);
- SSL_free(m_pssl);
- m_pssl = NULL;
- }
- if(m_pctx)
- {
- SSL_CTX_free(m_pctx);
- m_pctx = NULL;
- }
- if(m_sockfd > 2)
- {
- close(m_sockfd);
- m_sockfd = -1;
- }
- }
- bool CSSLComm::connected()
- {
- if(m_sockfd < 2) return false;
- struct timeval timeout;
- timeout.tv_sec = 0;
- timeout.tv_usec = 0;
- fd_set fdwrite;
- fd_set fdexcept;
- FD_ZERO(&fdwrite);
- FD_ZERO(&fdexcept);
- FD_SET(m_sockfd,&fdwrite);
- FD_SET(m_sockfd,&fdexcept);
- int ret = select(m_sockfd+1,NULL,&fdwrite,&fdexcept,&timeout);
- if(ret == -1)
- return false;
- if(ret > 0)
- {
- if(FD_ISSET(m_sockfd,&fdexcept))
- return false;
- else if(FD_ISSET(m_sockfd,&fdwrite))
- {
- int err = 0;
- socklen_t len = sizeof(err);
- int result = getsockopt(m_sockfd,SOL_SOCKET,SO_ERROR,(char*)&err,&len);
- if(result < 0 || err != 0)
- return false;
- return true;
- }
- }
- return false;
- }
- bool CSSLComm::ssl_connect(const char *host, int port, const char *certfile, const char *keyfile, const char* capath)
- {
- Reset();
- int err;
- /* Load encryption & hashing algorithms for the SSL program */
- SSL_library_init();
- /* Load the error strings for SSL & CRYPTO APIs */
- SSL_load_error_strings();
- /* Create an SSL_METHOD structure (choose an SSL/TLS protocol version) */
- m_pmeth = SSLv3_method();
- /* Create an SSL_CTX structure */
- m_pctx = SSL_CTX_new(m_pmeth);
- if(!m_pctx)
- {
- printf("Could not get SSL Context\n");
- return false;
- }
- /* Load the CA from the Path */
- if(SSL_CTX_load_verify_locations(m_pctx, NULL, capath) <= 0)
- {
- /* Handle failed load here */
- printf("Failed to set CA location...\n");
- ERR_print_errors_fp(stderr);
- return false;
- }
- /* Load the client certificate into the SSL_CTX structure */
- if (SSL_CTX_use_certificate_file(m_pctx, certfile, SSL_FILETYPE_PEM) <= 0)
- {
- printf("Cannot use Certificate File\n");
- ERR_print_errors_fp(stderr);
- return false;
- }
- /* Load the private-key corresponding to the client certificate */
- if (SSL_CTX_use_PrivateKey_file(m_pctx, keyfile, SSL_FILETYPE_PEM) <= 0)
- {
- printf("Cannot use Private Key\n");
- ERR_print_errors_fp(stderr);
- return false;
- }
- /* Check if the client certificate and private-key matches */
- if (!SSL_CTX_check_private_key(m_pctx))
- {
- printf("Private key does not match the certificate public key\n");
- return false;
- }
- /* Set up a TCP socket */
- m_sockfd = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
- if(m_sockfd == -1)
- {
- printf("Could not get Socket\n");
- return false;
- }
- memset (&m_server_addr, '\0', sizeof(m_server_addr));
- m_server_addr.sin_family = AF_INET;
- m_server_addr.sin_port = htons(port); /* Server Port number */
- m_phost_info = gethostbyname(host);
- if(m_phost_info)
- {
- /* Take the first IP */
- struct in_addr *address = (struct in_addr*)m_phost_info->h_addr_list[0];
- m_server_addr.sin_addr.s_addr = inet_addr(inet_ntoa(*address)); /* Server IP */
- }
- else
- {
- printf("Could not resolve hostname %s\n", host);
- return false;
- }
- /* Establish a TCP/IP connection to the SSL client */
- err = connect(m_sockfd, (struct sockaddr*) &m_server_addr, sizeof(m_server_addr));
- if(err == -1)
- {
- printf("Could not connect\n");
- return false;
- }
- /* An SSL structure is created */
- m_pssl = SSL_new(m_pctx);
- if(!m_pssl)
- {
- printf("Could not get SSL Socket\n");
- return false;
- }
- /* Assign the socket into the SSL structure (SSL and socket without BIO) */
- SSL_set_fd(m_pssl, m_sockfd);
- /* Perform SSL Handshake on the SSL client */
- err = SSL_connect(m_pssl);
- if(err == -1)
- {
- printf("Could not connect to SSL Server\n");
- return false;
- }
- return true;
- }
- void CSSLComm::PushNotification(const char *pToken,const char *pMsg)
- {
- CMyLock lock(&m_lock);
- if(!connected())
- {
- ssl_connect(APPLE_HOST, APPLE_PORT, RSA_CLIENT_CERT, RSA_CLIENT_KEY, CA_CERT_PATH);
- }
- int paylen = GenPayloadData(1,pMsg);
- GenPushData(pToken);
- int ret = SSL_write(m_pssl, (void*)&m_data, 35 + paylen);
- //printf("ret = %d \n",ret);
- }
- void CSSLComm::GenPushData(const char *pToken)
- {
- char *ptr = m_data.szToken;
- *ptr++ = 0;
- memcpy(ptr,&m_tokenLen,2);
- ptr += 2;
- memcpy(ptr,pToken,32);
- }
- int CSSLComm::GenPayloadData(int badgeNum,const char *pMsg)
- {
- char buf[256] = {0};
- char badgeBuf[3] = {0};
- strcpy(&m_data.szPayload[2], "{\"aps\":{");
- if(pMsg != NULL)
- {
- strcat(&m_data.szPayload[2], "\"alert\":");
- snprintf(buf, sizeof(buf)-1,"\"%s\",", pMsg);
- strcat(&m_data.szPayload[2],buf);
- }
- if(badgeNum > 99 || badgeNum < 0) badgeNum = 1;
- snprintf(badgeBuf, sizeof(badgeBuf)-1,"%d", badgeNum);
- strcat(&m_data.szPayload[2], "\"badge\":");
- strcat(&m_data.szPayload[2], badgeBuf);
- strcat(&m_data.szPayload[2], ",\"sound\":\"msg.wav\"}");
- /*
- int i = 0;
- while(payload->dictKey<i> != NULL && i < 5)
- {
- sprintf(tmpBuff, "\"%s\":\"%s\"", payload->dictKey<i>, payload->dictValue<i>);
- strcat(messageBuff, tmpBuff);
- if(i < 4 && payload->dictKey[i + 1] != NULL)
- {
- strcat(messageBuff, ",");
- }
- i++;
- }
- */
- snprintf(buf, sizeof(buf)-1,",\"%s\":\"%d\"", "forum_id",88);
- strcat(&m_data.szPayload[2],buf);
- snprintf(buf, sizeof(buf)-1,",\"%s\":\"%d\"", "topic_id",999);
- strcat(&m_data.szPayload[2],buf);
- strcat(&m_data.szPayload[2],"}");
- int len = strlen(&m_data.szPayload[2]);
- assert(len <= 256);
- uint16_t payload_len = htons(len);
- memcpy(m_data.szPayload,&payload_len,sizeof(payload_len));
- return len + 2;
- }
- #endif
0 0
- C++服务器的push推送通知的代码,SSL链接
- C++服务器的push推送通知的代码,SSL链接
- C++服务器的push推送通知的代码,SSL链接
- iPhone的Push(推送通知)功能原理
- 【iPhone Push】iPhone的Push(推送通知)功能原理浅析
- iPhone的Push(推送通知)功能原理浅析
- iPhone的Push(推送通知)功能原理浅析
- iPhone的Push(推送通知)功能原理浅析
- iPhone的Push(推送通知)功能原理浅析
- iPhone的Push(推送通知)功能原理浅析
- iPhone的Push(推送通知)功能原理浅析
- iPhone的Push(推送通知)功能原理浅析
- iPhone的Push(推送通知)功能原理浅析
- iPhone的Push(推送通知)功能原理浅析
- iPhone的Push(推送通知)功能原理浅析
- iPhone的Push(推送通知)功能原理浅析
- iPhone的Push(推送通知)功能原理浅析
- iPhone的Push(推送通知)功能原理浅析
- deepin系统下安装rubymine以及各种ruby编辑环境体验
- 内核工作队列workqueue
- JDK 8和jre 8的区别
- JSON的简单使用
- WPF 开始新的征程
- C++服务器的push推送通知的代码,SSL链接
- codeforces 55D D. Beautiful numbers(数位dp+数论)
- Windows下安装Python3的numpy、matplotlib、scipy包
- 1564 Play a game
- 华为OJ 查找组成一个偶数最接近的两个素数 Java实现
- VS2010应用程序工程中文件的组成结构
- uva 1374 power calculus
- android 之 数据库操作
- [前端] canvas进阶之图片缩放、水印及放大镜