ssl_read

前言

這裏的實現其實主要是基於libev,這個事件庫用起來自我感覺還是比較方便的,關於libev的使用方法大家可以去查一查,這裏不會做過多的陳述。

關於SSL_READ,相信大家在用到的時候可能會出現收到空的消息,然後就會不停地循環,這裏分享一下自己的處理方法供大家參考,有什麼問題可以提出來。

Libev+ssl_read的使用

static void socket_recv_cb(struct ev_loop *loop, struct ev_io *w, int revents)
{
    uint8_t buffer[DEVICE_INFO_ARRAY_MAX_SIZE*50] = {0};     //這裏定義了50K的空間來存放收到的數據
    int len = 0;
    int ret = 0, res = 0;
    struct _HEDGWMessage *resp;

    printf("[%s:%d] Recv server msg,start resolve...\n", __FUNCTION__, __LINE__);
    if(pssl) {      //這裏的pssl是上一篇文章裏定義的SSL
        while(1) {
            res = SSL_read(pssl, (void *)&len, RESQUEST_OFFSET);   //這裏由於我需要先收4個字節的數據來判斷真實數據的長度
            SSL_pending(pssl);
            ret = SSL_get_error(pssl, res);
            if(ret == SSL_ERROR_NONE) {
                if(res > 0) {
                    if(res == RESQUEST_OFFSET) {
                        len = ntohl(len);
                        printf("[%s:%d] Recv len == %d\n", __FUNCTION__, __LINE__, len);
                        memset(buffer, 0, sizeof(buffer));
                        if(SSL_read(pssl, (void *)buffer, len) != len) {
                            log_info("[%s:%d] Recv buffer len mismatch\n", __FUNCTION__, __LINE__);
                            break;
                        }
                        //這裏由於我用到了protobuf,這個大家可以不看,自定義自己的解析函數即可
                        resp = hedgwmessage__unpack(NULL, len, buffer);
                        resolve_recv_msg(resp);    
                        hedgwmessage__free_unpacked(resp, NULL);
                        break;
                    }
                } else {
                    if(SSL_get_error(pssl, ret) == SSL_ERROR_WANT_READ) {
                        continue;
                    }
                    break;
                }
            }
        }
    } else {
        printf("[%s:%d] SOCKET recv NULL, SSL is NULL,close...\n", __FUNCTION__, __LINE__);
        ev_io_stop(loop, w);
        return;
    }
}


void * start_request(void *arg)
{
    struct ev_loop *loop;
    struct ev_io socket_watcher;
    loop = ev_loop_new(EVFLAG_AUTO);    //這裏儘量用EVFLAG_AUTO,因爲如果系統時間有問題的話可能會造成ev_timer不準確
    ev_io_init(&socket_watcher, socket_recv_cb, sockfd, EV_READ);   //這裏的sockfd是上一篇文章裏返回的TCP sockfd
    ev_io_start(loop, &socket_watcher);

    ev_run(loop, 0);
}

//啓動線程來調度
if((pthread_create(&ssl_tid, NULL, start_request, NULL)) != 0) {
        printf("[%s:%d] Create ssl init pthread error\n", __FUNCTION__, __LINE__);
        return -1;
}
pthread_detach(ssl_tid);

備註:這裏只是代碼片段供大家參考,至於聲明和定義大家自己把控。。。

OK,關於OPENSSL的相關讀寫,這邊就已經全部展現給大家了,如果有什麼問題的話大家可以給我留言,一起進步!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章