openssl处理非阻塞socket


上篇博文是使用libevent加入ssl功能: 
http://blog.csdn.net/fly2010love/article/details/46459485 
文中说道,在处理非阻塞socket时需要注意的地方SSL_accept SSL_read SSL_wirte,本篇博文专门介绍如何处理socket在非阻塞下openssl如何处理

有网络程序开发经验的人都知道一个很头疼的问题,那就是在非阻塞的socket下 
如果使用事件驱动epoll的ET模式下,在读数据时,若一次没有全部读取, 
下次事件将要等到客户端再次发送数据时才会触发,那么这就存在一个问题, 
如果客户端不在发送数据了,那么这个链接就废了,本来内核缓冲区还有数据, 
并且加上之前读到的数据刚好是一个完整的请求,由于在事件触发时没有一次性 
读取完,所以导致了业务处理上检查包的时认为包接收不完整,所以在等待下次 
数据接收回调,SSL在非阻塞时同样存在这个问题,并且在accept时也会存在同样的 
问题,下面就此问题来进行解决,可能存在一些处理不够完善,欢迎大家吐槽指正

非阻塞socket下SSL_accept处理: 
这是上篇博文一样的将socket附加到SSL上的函数,请注意SSL_accept的处理

<code class="hljs coffeescript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">SSL* <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(0, 136, 0);">CEventBaseMgr</span>::CreateSSL(evutil_socket_t& fd)
{
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> <span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(!CConfiger::GetInstance()->GetEnableSSL())</span>
    {
        <span class="hljs-title" style="box-sizing: border-box;">return</span> <span class="hljs-title" style="box-sizing: border-box;">NULL</span>;
    }

    <span class="hljs-title" style="box-sizing: border-box;">SSL_CTX</span>* <span class="hljs-title" style="box-sizing: border-box;">ctx</span> = <span class="hljs-title" style="box-sizing: border-box;">NULL</span>;  
    <span class="hljs-title" style="box-sizing: border-box;">SSL</span>* <span class="hljs-title" style="box-sizing: border-box;">ssl</span> = <span class="hljs-title" style="box-sizing: border-box;">NULL</span>; 
    <span class="hljs-title" style="box-sizing: border-box;">ctx</span> = <span class="hljs-title" style="box-sizing: border-box;">SSL_CTX_new</span> <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(SSLv23_method())</span>;
    <span class="hljs-title" style="box-sizing: border-box;">if</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">( ctx == NULL)</span>
    {
        <span class="hljs-title" style="box-sizing: border-box;">printf</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"SSL_CTX_new error!\n"</span>)</span>;
        <span class="hljs-title" style="box-sizing: border-box;">return</span> <span class="hljs-title" style="box-sizing: border-box;">NULL</span>;
    }

    // 要求校验对方证书  
    <span class="hljs-title" style="box-sizing: border-box;">SSL_CTX_set_verify</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(ctx, SSL_VERIFY_NONE, NULL)</span>;  

    // 加载<span class="hljs-title" style="box-sizing: border-box;">CA</span>的证书  
    <span class="hljs-title" style="box-sizing: border-box;">if</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(!SSL_CTX_load_verify_locations(ctx, CA_CERT_FILE, NULL))</span>
    {
        <span class="hljs-title" style="box-sizing: border-box;">SSL_CTX_free</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(ctx)</span>;
        <span class="hljs-title" style="box-sizing: border-box;">printf</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"SSL_CTX_load_verify_locations error!\n"</span>)</span>;
        <span class="hljs-title" style="box-sizing: border-box;">return</span> <span class="hljs-title" style="box-sizing: border-box;">NULL</span>;
    }

    // 加载自己的证书  
    <span class="hljs-title" style="box-sizing: border-box;">if</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(SSL_CTX_use_certificate_file(ctx, SERVER_CERT_FILE, SSL_FILETYPE_PEM) <= <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>)</span>
    {
        <span class="hljs-title" style="box-sizing: border-box;">SSL_CTX_free</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(ctx)</span>;
        <span class="hljs-title" style="box-sizing: border-box;">printf</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"SSL_CTX_use_certificate_file error!\n"</span>)</span>;
        <span class="hljs-title" style="box-sizing: border-box;">return</span> <span class="hljs-title" style="box-sizing: border-box;">NULL</span>;
    }

    // 加载自己的私钥  
    <span class="hljs-title" style="box-sizing: border-box;">if</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(SSL_CTX_use_PrivateKey_file(ctx, SERVER_KEY_FILE, SSL_FILETYPE_PEM) <= <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>)</span>
    {
        <span class="hljs-title" style="box-sizing: border-box;">SSL_CTX_free</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(ctx)</span>;
        <span class="hljs-title" style="box-sizing: border-box;">printf</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"SSL_CTX_use_PrivateKey_file error!\n"</span>)</span>;
        <span class="hljs-title" style="box-sizing: border-box;">return</span> <span class="hljs-title" style="box-sizing: border-box;">NULL</span>;
    }

    // 判定私钥是否正确  
    <span class="hljs-title" style="box-sizing: border-box;">if</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(!SSL_CTX_check_private_key(ctx))</span>
    {
        <span class="hljs-title" style="box-sizing: border-box;">SSL_CTX_free</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(ctx)</span>;
        <span class="hljs-title" style="box-sizing: border-box;">printf</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"SSL_CTX_check_private_key error!\n"</span>)</span>;
        <span class="hljs-title" style="box-sizing: border-box;">return</span> <span class="hljs-title" style="box-sizing: border-box;">NULL</span>;
    }

    // 将连接付给<span class="hljs-title" style="box-sizing: border-box;">SSL</span>  
    <span class="hljs-title" style="box-sizing: border-box;">ssl</span> = <span class="hljs-title" style="box-sizing: border-box;">SSL_new</span> <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(ctx)</span>;
    <span class="hljs-title" style="box-sizing: border-box;">if</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(!ssl)</span>
    {
        <span class="hljs-title" style="box-sizing: border-box;">SSL_CTX_free</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(ctx)</span>;
        <span class="hljs-title" style="box-sizing: border-box;">printf</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"SSL_new error!\n"</span>)</span>;
        <span class="hljs-title" style="box-sizing: border-box;">return</span> <span class="hljs-title" style="box-sizing: border-box;">NULL</span>;
    }

    <span class="hljs-title" style="box-sizing: border-box;">SSL_set_fd</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(ssl, fd)</span>;  
    <span class="hljs-title" style="box-sizing: border-box;">bool</span> <span class="hljs-title" style="box-sizing: border-box;">isContinue</span> = <span class="hljs-title" style="box-sizing: border-box;">true</span>;
    <span class="hljs-title" style="box-sizing: border-box;">while</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(isContinue)</span>
    {
        <span class="hljs-title" style="box-sizing: border-box;">isContinue</span> = <span class="hljs-title" style="box-sizing: border-box;">false</span>;
        <span class="hljs-title" style="box-sizing: border-box;">if</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(SSL_accept(ssl) != <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)</span>
        {
            <span class="hljs-title" style="box-sizing: border-box;">int</span> <span class="hljs-title" style="box-sizing: border-box;">icode</span> = -1;
            <span class="hljs-title" style="box-sizing: border-box;">int</span> <span class="hljs-title" style="box-sizing: border-box;">iret</span> = <span class="hljs-title" style="box-sizing: border-box;">SSL_get_error</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(ssl, icode)</span>;
            <span class="hljs-title" style="box-sizing: border-box;">if</span> <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(iret == SSL_ERROR_WANT_READ)</span>
            {
                <span class="hljs-title" style="box-sizing: border-box;">isContinue</span> = <span class="hljs-title" style="box-sizing: border-box;">true</span>;
            }
            <span class="hljs-title" style="box-sizing: border-box;">else</span>
            {
                <span class="hljs-title" style="box-sizing: border-box;">SSL_CTX_free</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(ctx)</span>;
                <span class="hljs-title" style="box-sizing: border-box;">SSL_free</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(ssl)</span>;
                <span class="hljs-title" style="box-sizing: border-box;">ctx</span> = <span class="hljs-title" style="box-sizing: border-box;">NULL</span>;
                <span class="hljs-title" style="box-sizing: border-box;">ssl</span> = <span class="hljs-title" style="box-sizing: border-box;">NULL</span>;

                <span class="hljs-title" style="box-sizing: border-box;">break</span>;
            }
        }
        <span class="hljs-title" style="box-sizing: border-box;">else</span>
            <span class="hljs-title" style="box-sizing: border-box;">break</span>;
    }

    <span class="hljs-title" style="box-sizing: border-box;">return</span> <span class="hljs-title" style="box-sizing: border-box;">ssl</span>;
}</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li><li style="box-sizing: border-box; padding: 0px 5px;">79</li><li style="box-sizing: border-box; padding: 0px 5px;">80</li><li style="box-sizing: border-box; padding: 0px 5px;">81</li><li style="box-sizing: border-box; padding: 0px 5px;">82</li><li style="box-sizing: border-box; padding: 0px 5px;">83</li><li style="box-sizing: border-box; padding: 0px 5px;">84</li><li style="box-sizing: border-box; padding: 0px 5px;">85</li><li style="box-sizing: border-box; padding: 0px 5px;">86</li><li style="box-sizing: border-box; padding: 0px 5px;">87</li><li style="box-sizing: border-box; padding: 0px 5px;">88</li><li style="box-sizing: border-box; padding: 0px 5px;">89</li></ul>

这一段处理中

<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">bool</span> isContinue = <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">true</span>;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span>(isContinue)
    {
        isContinue = <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">false</span>;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(SSL_accept(ssl) != <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)
        {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> icode = -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> iret = SSL_get_error(ssl, icode);
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (iret == SSL_ERROR_WANT_READ)
            {
                isContinue = <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">true</span>;
            }
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span>
            {
                SSL_CTX_free(ctx);
                SSL_free(ssl);
                ctx = <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">NULL</span>;
                ssl = <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">NULL</span>;

                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span>;
            }
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span>
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span>;
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li></ul>

我们使用一个循环来进行处理,因为非阻塞时,socket的SSL底层进行身份和密钥证书协商是socket同样是阻塞的,故通过判断SSL_accept的返回值和SSL_get_error(ssl, icode);的返回值来确定是真的 
出现错误,还是没用完成accept等验证操作,accept也是一个socket可读事件 
所以判断事件的类型是:SSL_ERROR_WANT_READ,具体可查看SSL_accept的帮助文档

非阻塞socket下SSL_read处理:

<code class="hljs axapta has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> SslRecv(SSL* ssl, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span>* buffer, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> ilen)
{
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> ires = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">count</span> = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;;
    bool isCoutinue = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (isCoutinue)
    {
        ires = SSL_read(ssl, buffer + <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">count</span>, ilen - <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">count</span>);
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> nRes = SSL_get_error(ssl, ires);
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(nRes == SSL_ERROR_NONE)
        {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(ires > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>)
            {
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">count</span> += ires;
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">count</span> >= ilen)
                {
                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span>;
                }
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">continue</span>;
            }
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span>
        {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span>;
        }
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">count</span>;
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li></ul>

理论同上,通过判断SSL_get_error 的返回值来判断读是否出错,并且判断缓冲区 
的大小,若缓冲区足够大,且读回来的数据大于0,表示可能还有数据未读取完成 
需要偏移缓冲区,继续读取。

非阻塞socket下SSL_write处理:

<code class="hljs axapta has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> SslSend(SSL* ssl, const <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span>* buffer, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> ilen)
{
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> ires = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">count</span> = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;;
    bool isCoutinue = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (isCoutinue)
    {
        ires = SSL_write(ssl, buffer + <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">count</span>, ilen - <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">count</span>);
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> nRes = SSL_get_error(ssl, ires);
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(nRes == SSL_ERROR_NONE)
        {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(ires > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>)
            {
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">count</span> >= ilen)
                {
                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span>;
                }
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">count</span> += ires;
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">continue</span>;
            }
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (nRes == SSL_ERROR_WANT_READ)
        {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">continue</span>;
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span>
        {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span>;
        }
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">count</span>;
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li></ul>

在发送过程中处理也是类似,通过判断相应的返回值和错误码来判断发送 
是否失败,在这里有个疑惑:

<code class="hljs bash has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (nRes == SSL_ERROR_WANT_READ)
        {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">continue</span>;
        }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>

这一段代码中,加入了一个判断SSL_ERROR_WANT_READ事件类型,有些想不通的 
是,按理说应该是这个事件:SSL_ERROR_WANT_WRITE,但在调试过程中发现 
返回确实SSL_ERROR_WANT_READ,本人暂时的理解是:socekt链接成功 
以后应该是SSL_get_error在socket正常连接过程中都是SSL_ERROR_WANT_READ 
状态,忘有高手来解答疑惑,或者后面有时间自己在深入了解和调试试试

结束语: 
关于openssl的相关编程就告一段路了,后续有时间将继续更新关于libevent 
使用的技巧和相关需要注意的地方,相关文章只供参考,有相关处理不当的地方 
请读者自行优化处理。

版权声明:本文为博主原创文章,未经博主允许不得转载。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值