c - recv() 没有被 libevent 触发
问题描述
我正在尝试通过其管理套接字连接到本地 openvpn 客户端并查询其状态/状态。
我已经实现了带有 libevent 支持的后续程序。
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <event2/event.h>
#include <fcntl.h>
#include <string.h>
char message[1000], server_reply[2000];
struct event *ev, *ev1, *ev2;
int fd_set_blocking(int fd, int blocking)
{
int flags = fcntl(fd, F_GETFL, 0);
if (flags == -1) {
return 0;
}
if (blocking) {
flags &= ~O_NONBLOCK;
} else {
flags |= O_NONBLOCK;
}
return fcntl(fd, F_SETFL, flags) != -1;
}
void cb_func_hold_release(evutil_socket_t fd, short what, void *arg)
{
int sock = *(int *)arg;
struct timeval one_seconds = {1,0};
printf("IN CB CONNECT\n");
sprintf (message, "hold release\n");
if (send (sock, message, strlen (message), 0) < 0) {
printf("send failed\n");
}
event_add(ev1, NULL);
}
void cb_func_write(evutil_socket_t fd, short what, void *arg)
{
int sock = *(int *)arg;
printf("IN CB CHECKSTATUS\n");
sprintf (message, "status\n");
if (send (sock, message, strlen (message), 0) < 0) {
printf("send failed\n");
}
/*
int reclen = recv (sock, server_reply, 2000, 0);
if (reclen < 0) {
printf("recving failed");
} else {
if (reclen > 1) {
server_reply[reclen-1] = '\0';
}
printf("SERVER REPLT< %s\n", server_reply);
}
if (strstr(message, "CONNECTED")) {
printf("VPN CONNECTED");
}
*/
event_add(ev2, NULL);
if (event_pending(ev2,EV_READ|EV_PERSIST, NULL)) {
printf("ADDED READ EVENT\n");
}
}
void cb_func_read(evutil_socket_t fd, short what, void *arg)
{
int sock = *(int *)arg;
printf("IN CB READ\n");
int reclen = recv (sock, server_reply, 2000, 0);
if (reclen < 0) {
printf("recving failed");
} else {
if (reclen > 1) {
server_reply[reclen-1] = '\0';
}
printf("SERVER REPLY %s\n", server_reply);
}
if (strstr(message, "CONNECTED")) {
printf("VPN CONNECTED");
}
}
int main(void)
{
int flags;
int mgmretry = 0;
int sock = 0;
struct sockaddr_in server;
struct timeval five_seconds = {1,0};
struct event_base *base = event_base_new();
ev = event_new(base, sock, EV_TIMEOUT, cb_func_hold_release, &sock);
ev1 = event_new(base, sock, EV_WRITE, cb_func_write, &sock);
ev2 = event_new(base, sock, EV_READ, cb_func_read, &sock);
sock = socket (AF_INET, SOCK_STREAM, 0);
if (sock == -1) {
printf("COUILD NOT CREATE SOCKET\n");
exit(0);
}
fd_set_blocking(sock, 1);
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons (12345);
if (connect (sock, (struct sockaddr *)&server, sizeof (server)) < 0) {
printf("connecting failed\n");
exit(0);
}
event_add(ev, &five_seconds);
printf("DISPATCHING\n");
event_base_dispatch(base);
}
问题是未触发读取回调“cb_func_read”。我的期望是,在我从 cb_func_write() 向 vpn 发送“状态”消息后,会发回一些应该触发读取回调的数据,但这并没有发生。
如果我在写回调(注释部分)中的 send() 之后直接接收 recv(),我可以打印从 openvpn 发送的响应,以便这两者之间的通信正常工作。
解决方案
该事件不会触发,除非您使用event_add()
.
您只为ev
事件执行了此操作,但没有为ev1
and执行此操作ev2
。
推荐阅读
- python - 如何在 Python 中舍入 pandas 数据框的每个条目(这是一个元组)?
- facebook-audience-network - 脸书观众网络
- javascript - Bootstrap VueJS 表单选择添加组标签
- php - PHP 中的 MongoDB 聚合 $group 结果中缺少字段,但 Compass 中没有
- r - 是否有 R 函数将单个变量绘制为热图?
- python - IndexingError:Python 过滤器的索引器过多
- javascript - RazorPay:在 fetchPayment REST API 中出现 CORS 错误
- apache-spark - spark中Driver和Application manager有什么区别
- python - 在 python PyQt5 中添加 Qframes 和 Matplotlib
- javascript - 为什么我的异步函数在等待后返回待处理的承诺?