C++ libev每个fd有一个以上的观察者失败
我似乎无法在每个插座上安装两个观察者。。下面的代码根本不起作用,但如果我把这些调用混在一起(例如,为1个观察者调用init/set/start,然后为其他观察者调用),我只能让1个观察者工作。。这里有什么东西我遗漏得很严重吗。。。? 我不认为这与循环和设置有任何关系。。。我有1个接受循环(默认循环)和1个接受连接的循环。我尝试了这两种方法,在accept循环上接受连接后直接运行下面的代码,并通过ev_async_send(…),然后从其他io循环执行此代码。结果相同。 同样,在1个观察者上设置这两个事件也可以正常工作 多谢各位C++ libev每个fd有一个以上的观察者失败,c++,sockets,gcc,libev,C++,Sockets,Gcc,Libev,我似乎无法在每个插座上安装两个观察者。。下面的代码根本不起作用,但如果我把这些调用混在一起(例如,为1个观察者调用init/set/start,然后为其他观察者调用),我只能让1个观察者工作。。这里有什么东西我遗漏得很严重吗。。。? 我不认为这与循环和设置有任何关系。。。我有1个接受循环(默认循环)和1个接受连接的循环。我尝试了这两种方法,在accept循环上接受连接后直接运行下面的代码,并通过ev_async_send(…),然后从其他io循环执行此代码。结果相同。 同样,在1个观察者上设置这
ev_init (pSockWatcher->_wW, &CNetServer::send_cb);
ev_init (pSockWatcher->_wR, &CNetServer::recv_cb);
ev_io_set (pSockWatcher->_wW, pSockWatcher->_sd, EV_WRITE );
ev_io_set (pSockWatcher->_wR, pSockWatcher->_sd, EV_READ );
ev_io_start (loop, pSockWatcher->_wR);
ev_io_start (loop, pSockWatcher->_wW);
这里有一个例子,在一个套接字fd上有两个I/O观察程序,这对我来说似乎很好。但是,我使用的是ev_io_init()函数,而不是ev_init()和ev_set()
#包括
#包括
#包括
#包括
#包括
#包括
#包括
静态结构ev_循环*循环;
静态ev_定时器超时_观察程序;
静态ev\u io输入/输出观察程序;
静态电动汽车怠速观察装置;
静态int sock_fd;
//套接字输入监视器
断路器中的静态空隙(EV_P__EV_io*观察者,内部防护){
int r,t;
char-buf[1024];
对于(t=0;(r=read(sock_fd,buf,sizeof(buf)))>0;){
t+=r;
write(STDOUT_FILENO,buf,r);//将输入复制到STDOUT
如果(buf[r-1]='\n')中断;//一次操作一行
}
fprintf(stderr,“in:count=%d\n”,t);
如果(r==0){
fputs(“in:connection closed\n”,stderr);
ev_io_stop(循环和in_观察程序);//停止套接字观察程序
ev_break(循环,EVBREAK_ALL);//退出循环
}else如果(r<0){
佩罗(“阅读”);
}
}
//插座输出监视器
静态无效输出断路器(EV_P__EV_io*观察者,内部防护){
int r,t,lim;
char-buf[1024];
ev\u io\u停止(回路和输出观察者);
对于(t=0;tsizeof(buf))?sizeof(buf):lim-t))>0;){
t+=r;
如果(t>=lim)中断;
}
if(r<0){
佩罗(“书面”);
}
fprintf(stderr,“out:已完成发送,计数=%d\n”,t);
}
静态无效超时\u cb(EV\u P\uEV\u定时器*观察者,int revents){
fprintf(stderr,“超时:现在=%f\n”,ev_now(循环));
//如果可以的话,在插座上发送一堆东西
ev_io_启动(回路和输出监视程序);
}
静态无效空闲断路器(EV_P_EV_空闲*观察者,int revents){
静态长空闲计数=0;
fprintf(stderr,“空闲:计数=%ld\n”++空闲\u计数);
睡眠(1);//模拟做事情
}
int main(){
外部内部错误;
int master_fd;
int sock_opt=1;
内部连接端口=7000;
地址中的结构sockaddr\u;
索克伦·阿德伦;
//****设置套接字以接收数据需要以下内容****
master\u fd=套接字(AF\u INET,SOCK\u STREAM,0);
如果(主控_fd==-1){
佩罗(“插座”);
返回errno;
}
if(setsockopt(master_fd,SOL_SOCKET,SO_REUSEADDR,(char*)和sock_opt,sizeof(sock_opt))=-1){
perror(“setsockopt”);
返回errno;
}
addr.sin_family=AF_INET;
addr.sin\u addr.s\u addr=INADDR\u ANY;
地址sin_端口=htons(连接端口);
addrlen=sizeof(addr);
如果(绑定(主函数(结构sockaddr*)和地址,地址连)!=0){
佩罗(“绑定”);
返回errno;
}
如果(听(主控fd,3)!=0){
佩罗尔(“倾听”);
返回errno;
}
fprintf(stderr,“等待端口%d上的连接”,连接端口);
sock_fd=accept(master_fd,(结构sockaddr*)和addr,&addrlen);
如果(sock_fd==-1){
佩罗(“接受”);
返回errno;
}
fputs(“in:connection-builded\n”,stderr);
//****套接字结束设置代码****
//定义一个循环
循环=ev_默认_循环(0);
//定义一个重复计时器
ev_timer_init(&timeout_watcher,timeout_cb,5.0,5.0);
电动计时器启动(循环、超时和观察);
//定义空闲进程
ev_idle_init(&idle_watcher,idle_cb);
电动汽车怠速起动(环路和怠速观察装置);
//定义套接字数据接收器
ev_io_init(和in_watcher、in_cb、sock_fd、ev_READ);
ev_io_启动(回路和in_watcher);
//定义套接字数据写入完整监视程序
ev_io_init(&out_watcher、out_cb、sock_fd、ev_WRITE);
//循环
电动汽车运行(循环,0);
//清理
关闭(sock_fd);
关闭(主控室fd);
返回0;
}
没有人?:(任何一个例子,每个fd有两个观察者?谷歌没有任何…。谢谢你这个例子!我修复了我的问题,它与在…new struct ev_io;或类似的东西中使用struct关键字有关…我记不起我到底改变了什么,但这与此有关。我猜gcc没有分配正确大小的struct左右。..
#include <ev.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
static struct ev_loop *loop;
static ev_timer timeout_watcher;
static ev_io in_watcher, out_watcher;
static ev_idle idle_watcher;
static int sock_fd;
// socket input watcher
static void in_cb(EV_P_ ev_io *watcher, int revents) {
int r, t;
char buf[1024];
for (t = 0; (r = read(sock_fd, buf, sizeof(buf))) > 0;) {
t += r;
write(STDOUT_FILENO, buf, r); // copy input to stdout
if (buf[r-1] == '\n') break; // operate line-at-a-time
}
fprintf(stderr, "in: count = %d\n", t);
if (r == 0) {
fputs("in: connection closed\n", stderr);
ev_io_stop(loop, &in_watcher); // stop the socket watcher
ev_break(loop, EVBREAK_ALL); // exit the loop
} else if (r < 0) {
perror("read");
}
}
// socket output watcher
static void out_cb(EV_P_ ev_io *watcher, int revents) {
int r, t, lim;
char buf[1024];
ev_io_stop(loop, &out_watcher);
for (t = 0; t < sizeof(buf); t++) {
buf[t] = 'a' + (rand() % 26);
}
for (t = 0, lim = rand() % 10000 + 1000;
(r = write(sock_fd, buf, (lim - t > sizeof(buf)) ? sizeof(buf) : lim - t)) > 0;) {
t += r;
if (t >= lim) break;
}
if (r < 0) {
perror("write");
}
fprintf(stderr, "out: finished sending, count = %d\n", t);
}
static void timeout_cb(EV_P_ ev_timer *watcher, int revents) {
fprintf(stderr, "timeout: now = %f\n", ev_now(loop));
// send a bunch of stuff on the socket when able
ev_io_start (loop, &out_watcher);
}
static void idle_cb(EV_P_ ev_idle *watcher, int revents) {
static long idle_count = 0;
fprintf(stderr, "idle: count = %ld\n", ++idle_count);
sleep(1); // simulate doing stuff
}
int main() {
extern int errno;
int master_fd;
int sock_opt = 1;
int conn_port = 7000;
struct sockaddr_in addr;
socklen_t addrlen;
// **** the following is needed to set up a socket to receive data ****
master_fd = socket(AF_INET, SOCK_STREAM, 0);
if (master_fd == -1) {
perror("socket");
return errno;
}
if (setsockopt(master_fd, SOL_SOCKET, SO_REUSEADDR, (char *) &sock_opt, sizeof(sock_opt)) == -1) {
perror("setsockopt");
return errno;
}
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(conn_port);
addrlen = sizeof(addr);
if (bind(master_fd, (struct sockaddr *) &addr, addrlen) != 0) {
perror("bind");
return errno;
}
if (listen(master_fd, 3) != 0) {
perror("listen");
return errno;
}
fprintf(stderr, "awaiting a connection on port %d\n", conn_port);
sock_fd = accept(master_fd, (struct sockaddr *) &addr, &addrlen);
if (sock_fd == -1) {
perror("accept");
return errno;
}
fputs("in: connection established\n", stderr);
// **** end of socket setup code ****
// define a loop
loop = ev_default_loop(0);
// define a repeating timer
ev_timer_init (&timeout_watcher, timeout_cb, 5.0, 5.0);
ev_timer_start (loop, &timeout_watcher);
// define an idle process
ev_idle_init(&idle_watcher, idle_cb);
ev_idle_start (loop, &idle_watcher);
// define the socket data receiver
ev_io_init(&in_watcher, in_cb, sock_fd, EV_READ);
ev_io_start (loop, &in_watcher);
// define the socket data write complete watcher
ev_io_init(&out_watcher, out_cb, sock_fd, EV_WRITE);
// run the loop
ev_run(loop, 0);
// clean up
close(sock_fd);
close(master_fd);
return 0;
}