C++服务器的push推送通知的代码,SSL链接

来源:互联网 发布:淘宝搜索排名黑科技 编辑:程序博客网 时间:2024/05/16 14:40

附上原文地址:http://blog.csdn.net/zougangx/article/details/8126173

 

//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   


 

原创粉丝点击