当前位置:  编程技术>综合
本页文章导读:
    ▪ssl_server      #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> #include <sys/wait.h> #include <unistd.h> #includ.........
    ▪[细节决定B度]之回首一瞥cout<<"Hello,world"<<endl;             都说细节决定成败,我觉得的编程来说,特别是面试的时候细节最能决定的是关键时候你能装的程度,所以我想有个系列记录我遇到的各种我遇到的细节问题,.........
    ▪ssl_Client        #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> #i.........

[1]ssl_server
    来源: 互联网  发布时间: 2013-11-10

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <openssl/ssl.h>
#include <openssl/err.h>

#define MAXBUF 1024
/************关于本文档********************************************
*filename: ssl-server.c
*purpose: 演示利用 OpenSSL 库进行基于 IP层的 SSL 加密通讯的方法,这是服务器端例子
*********************************************************************/
int main(int argc, char **argv)
{
    int sockfd, new_fd;
    socklen_t len;
    struct sockaddr_in my_addr, their_addr;
    unsigned int myport, lisnum;
    char buf[MAXBUF + 1];
    SSL_CTX *ctx;

    if (argv[1])
        myport = atoi(argv[1]);
    else
        myport = 8000;

    if (argv[2])
        lisnum = atoi(argv[2]);
    else
        lisnum = 2;

    /* SSL 库初始化 */
    SSL_library_init();
    /* 载入所有 SSL 算法 */
    OpenSSL_add_all_algorithms();
    /* 载入所有 SSL 错误消息 */
    SSL_load_error_strings();
    /* 以 SSL V2 和 V3 标准兼容方式产生一个 SSL_CTX ,即 SSL Content Text */
    ctx = SSL_CTX_new(SSLv23_server_method());
    /* 也可以用 SSLv2_server_method() 或 SSLv3_server_method() 单独表示 V2 或 V3标准 */
    if (ctx == NULL) {
        ERR_print_errors_fp(stdout);
        exit(1);
    }
    /* 载入用户的数字证书, 此证书用来发送给客户端。 证书里包含有公钥 */
    if (SSL_CTX_use_certificate_file(ctx,"cacert.pem", SSL_FILETYPE_PEM) <= 0) {
        ERR_print_errors_fp(stdout);
        exit(1);
    }
    /* 载入用户私钥 */
    if (SSL_CTX_use_PrivateKey_file(ctx,"privkey.pem", 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 监听 */
    printf("socket creating......  \t\t");
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
       {
        perror("socket");
        exit(1);
       }
     else
       printf("socket created.\n");

    bzero(&my_addr, sizeof(my_addr));
    my_addr.sin_family = AF_INET;
    my_addr.sin_port = htons(myport);
    my_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    printf("bingding......\n");
    if (bind(sockfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr))
        == -1) {
        perror("bind");
        exit(1);
    } else
        printf("binded.\n");

    if (listen(sockfd, lisnum) == -1) {
        perror("listen");
        exit(1);
    } else
        printf("begin listen......\n");

    while (1) {
        SSL *ssl;
        len = sizeof(struct sockaddr);
        /* 等待客户端连上来 */
        if ((new_fd =
             accept(sockfd, (struct sockaddr *) &their_addr,
                    &len)) == -1) {
            perror("accept");
            exit(errno);
        } else
            printf("server: got connection from %s, port %d, socket %d\n",
                   inet_ntoa(their_addr.sin_addr),
                   ntohs(their_addr.sin_port), new_fd);

        /* 基于 ctx 产生一个新的 SSL */
        ssl = SSL_new(ctx);
        /* 将连接用户的 socket 加入到 SSL */
        SSL_set_fd(ssl, new_fd);
        /* 建立 SSL 连接 */
        if (SSL_accept(ssl) == -1) {
            perror("accept");
            close(new_fd);
            break;
        }

        /* 开始处理每个新连接上的数据收发 */
        bzero(buf, MAXBUF + 1);
        printf("[Server write]:");
        fflush(stdout);
        scanf("%s",buf);

        /* 发消息给客户端 */
        len = SSL_write(ssl, buf, strlen(buf));

        if (len <= 0) {
            printf("The message '%s' send failfully!errno:%d,error info:'%s'\n",buf, errno, strerror(errno));
            goto finish;
        } else
            printf("The message '%s' send successfully,the amount bytes sent :%d\n",
                   buf, len);

        bzero(buf, MAXBUF + 1);
        /* 接收客户端的消息 */
        len = SSL_read(ssl, buf, MAXBUF);
        if (len > 0)
            printf("接收到来自客户端的消息:'%s',共%d个字节的数据。\n",
                   buf, len);
        else
            printf
                ("消息接收失败!错误代码是%d,错误信息是'%s'\n",
                 errno, strerror(errno));
        /* 处理每个新连接上的数据收发结束 */
      finish:
        /* 关闭 SSL 连接 */
        SSL_shutdown(ssl);
        /* 释放 SSL */
        SSL_free(ssl);
        /* 关闭 socket */
        close(new_fd);
    }

    /* 关闭监听的 socket */
    close(sockfd);
    /* 释放 CTX */
    SSL_CTX_free(ctx);
    return 0;
}

作者:qianzhaotu 发表于2013-1-8 16:50:01 原文链接
    
[2][细节决定B度]之回首一瞥cout<<"Hello,world"<<endl;
    来源: 互联网  发布时间: 2013-11-10

       都说细节决定成败,我觉得的编程来说,特别是面试的时候细节最能决定的是关键时候你能装的程度,所以我想有个系列记录我遇到的各种我遇到的细节问题,以备不时之需啊。

       cout<<"Hello,world"<<endl;作为我真正学习写程序的起点我一直对其怀有感激之心,想到大一学C++的时候看到这个的时候觉得,这就是写程序吗?这就是我以前梦想的能够让电脑听我指挥,什么软件,游戏,病毒的开发吗?不像啊,这个也没什么作用啊,就看着个黑屏幕显示一句话,什么也做不了,那时也不懂得什么东西的学习都是漫长的过程,但是好在后面也没想太多,相比当时大多数兴趣被这黑屏浇灭而后再也没有研究过编程的同学,我还算幸运的莫名的坚持了下来。这几天,无意中看到一个C++教材第一页的hello world,脑子里面竟然想到当时我初学的时候老师跟我们说想把东西输出到屏幕上还可以用cout,cerr和clog,我还记得那个时候我还都试了试,发现都可以,但是也没有太在意其中的学问,只是疑问一样的功能为什么要搞三个名字,老师自然也是搬ppt的东西,也没有解释。后来我学会了查msdn,查到了这三个的区别在于重定向和缓冲,直到前几天,我居然在项目中遇到了有关这三个的问题,虽然不难解决,于是我觉得我还是有必要研究研究这个细节。

       一切都先从msdn开始比较靠谱,对于这三个的差异,msdn是这么解释的:

      The ostream class, through the derived class basic_ostream, supports the predefined stream objects:

  • cout   standard output

  • cerr   standard error with limited buffering

  • clog   similar to cerr but with full buffering

       这里面关键的一个词是buffering(什么?重定向,这里暂时没有看到,生命有限,一次不能研究的太多),buffer存在于计算机软硬件的各个方面,缓冲区的意义很好理解,最大的好处无非是可以提高效率,每天跑到银行存1000块钱和你十天凑齐10000块钱一次性向银行存入,所耗费的时间果断不能是一样的,所以无论在哪个方面缓冲都是人类的好朋友啊。这三个的差别从字面上看,第一个根本没有提buffering什么事,第二个有limited buffering,第三个是full buffering,有什么区别呢,先从第一个开始吧,继续在msdn中查找cout,看看这家伙怎么说的。让人是失望的是这里面基本没什么有用的信息,但是都说超链接改变世界,这里面的example有个cerr的超连接,正好它也排在第二个,顺手看看cerr好了,里面是这样描述的:

       The object controls unbuffered insertions to the standard error output as a byte stream. Once the object is constructed, the expression cerr.flags & unitbuf is nonzero.

       对比cout和前面的内容,unbuffered这个关键词再一次引起我们的关注,另外后面还多了一句话,提到了flags和unitbuf,在看了clog发现和cout没什么差别之后,每一个发育自然并且想研究一下的人都会查看一下unitbuf或者flags。查看flags发现这是一个和fmtflags相关的函数,而且后面还有一个例子:

#include <iostream>
#include <fstream>

int main ( ) 
{
   using namespace std;
   cout << cout.flags( ) << endl;
   cout.flags( ios::dec | ios::boolalpha );
   cout << cout.flags( );
}

      运行一下会查看到cout的flag值,会看到输出是两个很奇怪的整数531和16896,这个时候就要去看看fmtflags到底是什么,msdn上是这么写的:

Constants to specify the appearance of output.

 
static const fmtflags boolalpha(15), dec(10), fixed(14), hex(12),
   internal(9), left(7), oct(11), right(8), scientific(13),
   showbase(4), showpoint(5), showpos(6), skipws(1), unitbuf(2),
   uppercase(3), adjustfield, basefield, floatfield;

      第一反应是这是什么玩意儿,还好msdn是高大全的参考,在Remark部分可以看到如下语句:

      Supports the manipulators in ios.

      The type is a bitmask type that describes an object that can store format flags. 

      两层含义,第一个支持ios里面的操作符,第二个是这是一个bitmask类型,也就是说上面的18个fmtflags类型定义的玩意儿都是这个类型的,ios里面的操作符很好理解,就是那些可以定义cout(当然同样作为输出流的cerr,clog也是可以被定义的)格式的东西,比如最简单的cout<<hex<<12;可以输出十六进制的12,也就是说fmtflags这个的作用就是使用另一种方式设定格式,设定的方法前面那个例子中也显示了,虽然是定义了18个fmtflags变量,但是在这个词条的底部也说明了最后三个是前面15个某些的组合,也就是说可以大胆的猜想flags有15位,具体这15个具体有什么作用,对此有兴趣的可以继续探究,上面每个变量旁边的括号中的数字是我亲测得每个对应的flags的位,假设最低位是从1开始的。

      另外,上面的程序531转换成二进制就是1000000001,也就是默认的cout设定的是dec和skipws两个位,skipws全名叫做skipwhitespace,这也很容易解释了cout的时候输出的十进制的数并且能够忽略前导空格,这算一个细节吧。

     在所有的flag里面,凭借一股风骚的意识你应该能发现有一个很眼熟啊--unitbuf,这个在前面cerr的说明里出现过,滚动一下鼠标可以发现cerr的说明中说这个位在cerr里面是非0的,而其余两个没有特别说明,那么我们就看看初始情况下clog和cerr的flag是什么,可以发现clog和cout是一样的,cerr却是1000000011,是不是有种看破的感觉,unitbuf既然有个buf,再加上cerr关于buffer的特别说明,可以猜想这个位就是控制buf的,再看看它的说明:

      unitbuf, to flush output after each insertion.

      翻译成中文就是每次输出的时候刷新输出,这句话在你什么也不知道的时候确实很疑惑,什么叫flush?前面说了这里面的符号位和ios的操作都是对应的,那么看看ios里面有什么相关的内容好了,找到ios members可以看到其中有个函数也是较unitbuf,这个时候就得赶紧点进去看看,Remark部分是这么写的:

     Note that endl also flushes the buffer.

     如果你从没有接触过这方面的内容,那么恭喜你,除了endl能换行之外,你至少知道了endl还可以刷新缓冲区,现在面临一个新问题,什么叫flushes the buffer,msdn不好找了,这就要回到缓冲区这个概念上来了。

      所谓缓冲区前面已经大概的解释了,你每天能赚1000(貌似有点多),然后你去存银行,这就是没有缓冲,但是你嫌这样太麻烦,你决定先攒几天钱再存银行,这样的话就是有缓存。但是总会有个条件让你达到要去存这个行为,这个条件或者是到了多少天,或者是到了多少钱,或者是你老婆迫使你赶紧去存,因为身上现金多了容易遭抢啊或者现金多了容易起干坏事,毕竟男人的银行卡一般都不在自己身上。但是事务都有两面性,虽然你每天存很耗时间,但是至少保证比好几天一存的安全性大(假设银行是信得过的)。

      输出缓冲区和上面这个过程也很像,如果不是设置的强制刷新的这个位,那么缓冲区只能在两种情况下刷新,第一个是缓冲区满了(时间到了或者钱总量到了),或者是强制要其刷新,比如使用了endl,flush等等(你老婆叫你去存钱),或者设置了unitbuf位。回到这三个输出流上面来,cerr既然设置了unitbuf项的位,它每次输出都会刷新输出缓冲区,这样的好处就是在程序出了一些特殊错误的情况下仍然能够有输出(费时但是安全),比如递归堆栈崩溃,而cout不会,那么刷新缓冲区是往哪儿刷新呢?在这里是往输出设备(不一定是屏幕),通俗的说就是如果刷新没有进行,那么就不会显示在控制台的窗口上,好了,费了这么多话,最关键的要眼见为实,怎么样才能看到这一个现象呢?按照上面费的这么多话,cerr和cout在表现上应该是不同的,所以我们用这两个试试看。

     想看到这个过程,我决定用一个Sleep,用

    
[3]ssl_Client
    来源: 互联网  发布时间: 2013-11-10

 

#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 <openssl/ssl.h>
#include <openssl/err.h>

#define MAXBUF 1024

void ShowCerts(SSL * ssl)
{
    X509 *cert;
    char *line;

    cert = SSL_get_peer_certificate(ssl);
    if (cert != NULL) {
        printf("The data certificate info:\n");
        line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
        printf("certificate: %s\n", line);
        free(line);
        line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
        printf("publish author: %s\n", line);
        free(line);
        X509_free(cert);
    } else
        printf("No certificate info\n");
}
/************关于本文档********************************************
*filename: ssl-client.c
*purpose: 演示利用 OpenSSL 库进行基于 IP层的 SSL 加密通讯的方法,这是客户端例子
*********************************************************************/
int main(int argc, char **argv)
{
    int sockfd, len;
    struct sockaddr_in dest;
    char buffer[MAXBUF + 1];
    SSL_CTX *ctx;
    SSL *ssl;

   /*( if (argc != 3) {
        printf("参数格式错误!正确用法:IP Port\n");
        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);
    }

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

    /* 初始化服务器端(对方)的地址和端口信息 */
    printf("address creating...... \t\t");
    bzero(&dest, sizeof(dest));
    dest.sin_family = AF_INET;
    dest.sin_port = htons(8000);
    if (inet_aton("10.70.253.201", (struct in_addr *) &dest.sin_addr.s_addr) == 0) {
        perror(argv[1]);
        exit(errno);
    }
    printf("address created.\n");

    /* 连接服务器 */
    printf("server connecting......\n\t\t");
    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("\n\nConnected with %s encryption\n", SSL_get_cipher(ssl));
        ShowCerts(ssl);
    }

    /* 接收对方发过来的消息,最多接收 MAXBUF 个字节 */
    bzero(buffer, MAXBUF + 1);
    /* 接收服务器来的消息 */
    len = SSL_read(ssl, buffer, MAXBUF);
    if (len > 0)
        printf("[Cleint recv]:%s,the bytes:%d。\n",
               buffer, len);
    else {
        printf("error number:%d,error info:%s\n",
             errno, strerror(errno));
        goto finish;
    }
    bzero(buffer, MAXBUF + 1);
    printf("[Client send]:");
    fflush(stdout);
    scanf("%s",buffer);
    /* 发消息给服务器 */
    len = SSL_write(ssl, buffer, strlen(buffer));
    if (len < 0)
        printf
            ("消息'%s'发送失败!错误代码是%d,错误信息是'%s'\n",
             buffer, errno, strerror(errno));
    else
        printf("send %s successfully the bytes:%d\n",
               buffer, len);

  finish:
    /* 关闭连接 */
    SSL_shutdown(ssl);
    SSL_free(ssl);
    close(sockfd);
    SSL_CTX_free(ctx);
    return 0;
}

 

作者:qianzhaotu 发表于2013-1-8 16:48:39 原文链接
阅读:28 评论:0 查看评论

    
最新技术文章:
▪error while loading shared libraries的解決方法    ▪版本控制的极佳实践    ▪安装多个jdk,多个tomcat版本的冲突问题
▪简单选择排序算法    ▪国外 Android资源大集合 和个人学习android收藏    ▪.NET MVC 给loading数据加 ajax 等待loading效果
▪http代理工作原理(3)    ▪关注细节-TWaver Android    ▪Spring怎样把Bean实例暴露出来?
▪java写入excel2007的操作    ▪http代理工作原理(1)    ▪浅谈三层架构
▪http代理工作原理(2)    ▪解析三层架构……如何分层?    ▪linux PS命令
▪secureMRT Linux命令汉字出现乱码    ▪把C++类成员方法直接作为线程回调函数    ▪weak-and算法原理演示(wand)
▪53个要点提高PHP编程效率    ▪linux僵尸进程    ▪java 序列化到mysql数据库中
▪利用ndk编译ffmpeg    ▪活用CSS巧妙解决超长文本内容显示问题    ▪通过DBMS_RANDOM得到随机
▪CodeSmith 使用教程(8): CodeTemplate对象    ▪android4.0 进程回收机制    ▪仿天猫首页-产品分类
▪从Samples中入门IOS开发(四)------ 基于socket的...    ▪工作趣事 之 重装服务器后的网站不能正常访...    ▪java序列化学习笔记
▪Office 2010下VBA Addressof的应用    ▪一起来学ASP.NET Ajax(二)之初识ASP.NET Ajax    ▪更改CentOS yum 源为163的源
▪ORACLE 常用表达式    ▪记录一下,AS3反射功能的实现方法    ▪u盘文件系统问题
▪java设计模式-观察者模式初探    ▪MANIFEST.MF格式总结    ▪Android 4.2 Wifi Display核心分析 (一)
▪Perl 正则表达式 记忆方法    ▪.NET MVC 给loading数据加 ajax 等待laoding效果    ▪java 类之访问权限
▪extjs在myeclipse提示    ▪xml不提示问题    ▪Android应用程序运行的性能设计
▪sharepoint 2010 自定义列表启用版本记录控制 如...    ▪解决UIScrollView截获touch事件的一个极其简单有...    ▪Chain of Responsibility -- 责任链模式
▪运行skyeye缺少libbfd-2.18.50.0.2.20071001.so问题    ▪sharepoint 2010 使用sharepoint脚本STSNavigate方法实...    ▪让javascript显原型!
▪kohana基本安装配置    ▪MVVM开发模式实例解析    ▪sharepoint 2010 设置pdf文件在浏览器中访问
▪spring+hibernate+事务    ▪MyEclipse中文乱码,编码格式设置,文件编码格...    ▪struts+spring+hibernate用jquery实现数据分页异步加...
▪windows平台c++开发"麻烦"总结    ▪Android Wifi几点    ▪Myeclipse中JDBC连接池的配置
▪优化后的冒泡排序算法    ▪elasticsearch RESTful搜索引擎-(java jest 使用[入门])...    ▪MyEclipse下安装SVN插件SubEclipse的方法
▪100个windows平台C++开发错误之七编程    ▪串口转以太网模块WIZ140SR/WIZ145SR 数据手册(版...    ▪初识XML(三)Schema
▪Deep Copy VS Shallow Copy    ▪iphone游戏开发之cocos2d (七) 自定义精灵类,实...    ▪100个windows平台C++开发错误之八编程
▪C++程序的内存布局    ▪将不确定变为确定系列~Linq的批量操作靠的住...    ▪DIV始终保持在浏览器中央,兼容各浏览器版本
▪Activity生命周期管理之三——Stopping或者Restarti...    ▪《C语言参悟之旅》-读书笔记(八)    ▪C++函数参数小结
▪android Content Provider详解九    ▪简单的图片无缝滚动效果    ▪required artifact is missing.
▪c++编程风格----读书笔记(1)    ▪codeforces round 160    ▪【Visual C++】游戏开发笔记四十 浅墨DirectX教程...
▪【D3D11游戏编程】学习笔记十八:模板缓冲区...    ▪codeforces 70D 动态凸包    ▪c++编程风格----读书笔记(2)
▪Android窗口管理服务WindowManagerService计算Activity...    ▪keytool 错误: java.io.FileNotFoundException: MyAndroidKey....    ▪《HTTP权威指南》读书笔记---缓存
▪markdown    ▪[设计模式]总结    ▪网站用户行为分析在用户市场领域的应用
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3