原帖:
我正在用libevent和zmq在C编程中编写一个服务。
使用PUSH-PULL模式将Msg从python代码推送到C服务。
从zmq套接字接收的fd:

void *receiver = zmq_socket (base.zmq_ctx, ZMQ_PULL);
zmq_connect (receiver, "tcp://localhost:5557");
int fd=0;
size_t fd_len = sizeof(fd);
zmq_getsockopt (receiver, ZMQ_FD, &fd, &fd_len);

使用Libevent,向fd注册用于持久读取的事件
struct event *read_data_on_zmq =event_new(base.evbase, fd, EV_READ | EV_PERSIST , read_data_on_zmq_cb,receiver);
event_add(read_data_on_zmq,NULL);
event_base_dispatch(base.evbase);

在回调方法上,我正在做一个非阻塞接收
void read_data_on_zmq_cb(evutil_socket_t fd, short what, void *arg)
{
    char *msg = calloc(1024,sizeof(char));
    int size = zmq_recv (receiver, msg, 255, ZMQ_DONTWAIT);
    if (size != -1)
    {
        puts ("is size is not -1");
        printf("msg = %s\n",msg);
    }
}

在python代码中,我不断地向套接字发送消息。
import zmq
import time

c=zmq.Context()
s=c.socket(zmq.PUSH)
s.bind('tcp://127.0.0.1:5557')
while(True):
    s.send("abc")
    time.sleep(2)

问题是我只能接收一次消息,之后事件回调就永远不会被命中。
如果我在zmq_recv之后在zmq_cb上的read_data_内部进行zmq_connect,那么它可以正常工作,但我想这是多余的,不是正确的方法这里有什么问题?
编辑1:
除了在执行ZMQ_recv()之后检查ZMQ_事件外,还需要获取所有消息,因为ZMQ是边缘触发的这里有一个关于边缘触发通知的很好的解释http://funcptr.net/2012/09/10/zeromq---edge-triggered-notification/
所以最终我的事件回调看起来
void read_data_on_zmq_cb(evutil_socket_t fd, short what, void *arg)
{
    unsigned int     zmq_events;
    size_t           zmq_events_size  = sizeof(zmq_events);
    char *msg=NULL;

    zmq_getsockopt (receiver, ZMQ_EVENTS, &zmq_events, &zmq_events_size);

    while(zmq_events & ZMQ_POLLIN)
    {
        msg = calloc(1024,sizeof(char));
        int size = zmq_recv (receiver, msg, 255, ZMQ_DONTWAIT);
        if (size != -1) {
        #ifdef DEBUG
            printf("msg = %s\n",msg);
        #endif
            //return msg;
        }
        zmq_getsockopt (receiver, ZMQ_EVENTS, &zmq_events, &zmq_events_size);
    }
}

最佳答案

请阅读我的EDIT1以获得完整的答案和代码。
问题是:
在执行ZMQ_recv()之后,我没有重新检查ZMQ_事件,因为套接字的状态发生了变化
当时。
如此呼唤

zmq_getsockopt (receiver, ZMQ_EVENTS, &fd, &fd_size);

在zmq_recv()解决了我的问题之后。

关于c - libevent kqueue不适用于从zmq_getsockopt()返回的fd,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16356286/

10-11 16:42