IOS push(C语言代码)

原理请参考:http://blog.csdn.net/bytxl/article/details/16981931

直接上代码:

#include <stdio.h>  
#include <string.h>  
#include <errno.h>  
#include <sys/socket.h>  
#include <resolv.h>  
#include <stdlib.h>  
#include <netinet/in.h>  
#include <arpa/inet.h>  
#include <unistd.h>  
#include <netdb.h>
#include <openssl/ssl.h>  
#include <openssl/err.h>  
  
#define MAXBUF 8192  


extern int h_errno;

/*
void ShowCerts(SSL * ssl)  
{  
    X509 *cert;  
    char *line;  
  
    cert = SSL_get_peer_certificate(ssl);  
    if (cert != NULL) {  
        printf("数字证书信息:\n");  
        line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);  
        printf("证书: %s\n", line);  
        free(line);  
        line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);  
        printf("颁发者: %s\n", line);  
        free(line);  
        X509_free(cert);  
    } else  
        printf("无证书信息!\n");  
}  
*/


static char * domain2ip( char *psz_domainname )
{
    struct hostent *p_hostent;
    
    if ( !psz_domainname )
        return NULL;
    
    p_hostent = gethostbyname( psz_domainname );
    if ( p_hostent == NULL )
    {
        printf( "error in gethostbyname: %s\n", hstrerror( h_errno ) );
        return NULL;
    }
    else
    {
        printf( "name: %s\naddrtype; %d\naddrlength: %d\n", p_hostent->h_name, p_hostent->h_addrtype, 
            p_hostent->h_length );
        printf( "ip address: %s\n", inet_ntoa(*(struct in_addr*)p_hostent->h_addr_list[0]));
        return inet_ntoa(*(struct in_addr*)p_hostent->h_addr_list[0]);
    }
}

//return value should be freeed outsid
// every 2 char to one char
static unsigned char* hex2str_2(char* str,int len)
{
    unsigned char* psz_result =NULL;
    int i,n;
    char psz_two[2];

    i = n = 0;

    do
    {
        psz_result = ( unsigned char * )malloc( len/2 + 2 );
        if (NULL == psz_result)
        {
            break;
        }
        memset( psz_result, 0, len/2 + 2 );

        while( i < len )
        {
            psz_two[0] = str[i];
            // 97 ~ 102: a ~ f
            // 65 ~ 70 : A ~ F
            // 48 ~ 57 : 0 ~ 1
            if ( psz_two[0] >= 97 && psz_two[0] <= 102 )
            {
                psz_two[0] = psz_two[0] - 87;
            }
            else if ( psz_two[0] >= 65 && psz_two[0] <= 79 )
            {
                psz_two[0] = psz_two[0] - 55;
            }
            else if ( psz_two[0] >= 48 && psz_two[0] <= 57 )
            {
                psz_two[0] = psz_two[0] - 48;
            }
            else
            {
                return NULL;
            }
            
            psz_two[1] = str[i+1] ? str[i+1] : 0;
            if ( psz_two[1] >= 97 && psz_two[1] <= 102 )
            {
                psz_two[1] = psz_two[1] - 87;
            }
            else if ( psz_two[1] >= 65 && psz_two[1] <= 70 )
            {
                psz_two[1] = psz_two[1] - 55;
            }
            else if ( psz_two[1] >= 48 && psz_two[1] <= 57 )
            {
                psz_two[1] = psz_two[1] - 48;
            }
            else
            {
                return NULL;
            }
            
            psz_result[n++] = 16 * psz_two[0] + psz_two[1]; 
            i += 2;
        }
        psz_result[n] = 0;
    }while(0);

    return psz_result;
}



/************关于本文档******************************************** 
*filename: ssl-client.c 
*purpose: 演示利用 OpenSSL 库进行基于 IP层的 SSL 加密通讯的方法,这是客户端例子 
*wrote by: zhoulifa(zhoulifa@163.com) 周立发(http://zhoulifa.bokee.com) 
Linux爱好者 Linux知识传播者 SOHO族 开发者 最擅长C语言 
*date time:2007-02-02 20:10 
*Note: 任何人可以任意复制代码并运用这些文档,当然包括你的商业用途 
* 但请遵循GPL 
*Thanks to:Google 
*Hope:希望越来越多的人贡献自己的力量,为科学技术发展出力 
* 科技站在巨人的肩膀上进步更快!感谢有开源前辈的贡献! 
*********************************************************************/  
int main(int argc, char **argv)  
{  
    int sockfd, len;  
    struct sockaddr_in dest;  
    unsigned char buffer[MAXBUF + 1];  
    SSL_CTX *ctx;  
    SSL *ssl;  
    char psz_ip[24] = {0};

    
    if (argc != 5) {  
        printf( "usage:\n\t%s Domainname port Certificate(include unencrypted key)"
            "\n\tfor example:\t%s gateway.sandbox.push.apple.com 2195 cert.pem\n",
             argv[0], argv[0]);
        exit(0);
    }
    
  
    /* SSL 库初始化,参看 ssl-server.c 代码 */  
    SSL_library_init();  
    OpenSSL_add_all_algorithms();  
    SSL_load_error_strings();  
    ctx = SSL_CTX_new(SSLv23_client_method());  
    if (ctx == NULL) {  
        ERR_print_errors_fp(stdout);  
        exit(1);  
    }

    /* 载入用户的数字证书, 此证书用来发送给客户端。 证书里包含有公钥 */
    if (SSL_CTX_use_certificate_file(ctx, argv[3], SSL_FILETYPE_PEM) <= 0) {
        ERR_print_errors_fp(stdout);
        exit(1);
    }

    
    // 载入用户私钥 
    if (SSL_CTX_use_PrivateKey_file(ctx, argv[4], SSL_FILETYPE_PEM) <= 0) {
        ERR_print_errors_fp(stdout);
        exit(1);
    }
    //  检查用户私钥是否正确 
    if (!SSL_CTX_check_private_key(ctx)) {
        ERR_print_errors_fp(stdout);
        exit(1);
    }
    


    /* 创建一个 socket 用于 tcp 通信 */  
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {  
        perror("Socket");  
        exit(errno);  
    }  
    printf("socket created\n");  

    strncpy( psz_ip, domain2ip( argv[1] ), sizeof( psz_ip ) );
    //strncpy( psz_ip, argv[1], sizeof( psz_ip ) );
    /* 初始化服务器端(对方)的地址和端口信息 */  
    bzero(&dest, sizeof(dest));  
    dest.sin_family = AF_INET;  
    dest.sin_port = htons(atoi(argv[2]));  
    if (inet_aton(psz_ip, (struct in_addr *) &dest.sin_addr.s_addr) == 0) {  
        perror(argv[1]);  
        exit(errno);  
    }  
    printf("address created\n");  
  
    /* 连接服务器 */  
    if (connect(sockfd, (struct sockaddr *) &dest, sizeof(dest)) != 0) {  
        perror("Connect ");  
        exit(errno);  
    }  
    printf("server connected\n");  
  
    /* 基于 ctx 产生一个新的 SSL */  
    ssl = SSL_new(ctx);  
    SSL_set_fd(ssl, sockfd);  
    /* 建立 SSL 连接 */  
    if (SSL_connect(ssl) == -1)  
        ERR_print_errors_fp(stderr);  
    else {  
        printf("Connected with %s encryption\n", SSL_get_cipher(ssl));  
        //ShowCerts(ssl);  
    }  
    
    /* 发消息给服务器 */  
    char psz_payload[128] = {0};
    strncpy( psz_payload, 
        "{\"aps\":{\"alert\":\"A test message from cylan1\",\"badge\":1,\"sound\":\"default\"}}",
        sizeof( psz_payload ) -1 );
    bzero(buffer, MAXBUF + 1);  

    //unsigned char *psz_devicetoken_bin = 
    //    hex2str_2( "cbb4b3ca1932e9ad4e761ac0da2e3cf47178f7fd2029a927036a5afb81f1373f", 64 );
    unsigned char *psz_devicetoken_bin = 
        hex2str_2( "ee03ee86c6c57219d167d06f1fae87b09e857a2d635ffacc71046f4e1974594f", 64 );

    printf( "\nint value devicetoken:\n" );
    int i_tmp = 0;
    for ( i_tmp = 0; i_tmp < strlen( ( char * )psz_devicetoken_bin ); i_tmp ++ )
    {
        printf( "psz_devicetoken_bin[%d]: %d\n", i_tmp, psz_devicetoken_bin[i_tmp] );
    }
    printf ( "\npsz_devicetoken_bin: %s\n", psz_devicetoken_bin );
    printf ( "\nstrlen( psz_payload ): %d\n", ( int )strlen( psz_payload ) );
    
    buffer[0] = 0;
    buffer[1] = 0;
    buffer[2] = 32;
    memcpy( buffer + 3, psz_devicetoken_bin, 32 ); 
    buffer[35] = 0;
    buffer[36] = strlen( psz_payload );
    memcpy( buffer + 37, psz_payload, strlen( psz_payload ) );
    
    // 37 bytes before psz_payload
    len = SSL_write(ssl, buffer, strlen( psz_payload ) + 37 );  
    if (len < 0)  
        printf  
            ("\n消息'%s'发送失败!错误代码是%d,错误信息是'%s', len: %d\n",  
             buffer, errno, strerror(errno), len);  
    else  
        printf("\n消息'%s'发送成功,共发送了%d个字节!\n",  
               buffer, len);  

    /* 接收对方发过来的消息,最多接收 MAXBUF 个字节 */  
    bzero(buffer, MAXBUF + 1);  
    /* 接收服务器来的消息 */  
    len = SSL_read(ssl, buffer, MAXBUF);  
    if (len > 0)  
        printf("接收消息成功:'%s',共%d个字节的数据\n",  
               buffer, len);  
    else {  
        printf  
            ("消息接收失败!错误代码是%d,错误信息是'%s'\n",  
             errno, strerror(errno));  
        goto finish;  
    }  
  
  finish:  
    /* 关闭连接 */  
    SSL_shutdown(ssl);  
    SSL_free(ssl);  
    close(sockfd);  
    SSL_CTX_free(ctx);  
    return 0;  
}  

编译:

gcc -g -Werror -Wall ./push.c -o ./push -L /usr/lib -lssl -lcrypto

运行:

./push gateway.sandbox.push.apple.com 2195 ./aps_development_merge.pem ./aps_development_unencrypted.key

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值