前言
這裏的實現其實主要是基於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的相關讀寫,這邊就已經全部展現給大家了,如果有什麼問題的話大家可以給我留言,一起進步!!!