前言
这里的实现其实主要是基于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的相关读写,这边就已经全部展现给大家了,如果有什么问题的话大家可以给我留言,一起进步!!!