C++服务器的push推送通知的代码,SSL链接
来源:互联网 发布:高斯键盘知乎 编辑:程序博客网 时间:2024/04/30 15:15
//SSLComm.h
#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
- 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(推送通知)功能原理浅析
- 查询redo logfile的使用率 tablespace 的自由空间
- 2012-10-29
- Easui中datagrid实现动态控制columns
- Redis学习笔记0--redis.conf配置项说明
- Hiberanate的拦截器和监听事件
- C++服务器的push推送通知的代码,SSL链接
- 求一个Vb.net 2005导出Excel 的类
- VC调试无法加断点,代码版本不一致的解决方法
- 计算文件的大小
- 对某招聘网站的一次友情检查
- 【词条】C++编译、链接过程
- 一个小题目
- CSS 后代选择器
- [转载]Android 异常和解决方法积累