Skip to content

zmq_poll does not trigger ZMQ_POLLIN event in some successful connections #3161

@cuteshell

Description

@cuteshell

Issue description

I use ZMQ_DEALER connect to ZMQ_ROUTER, and listening to events with zmq_poll, but when a client reconnect, the zmq_poll may be not trigger ZMQ_POLLIN event.

Environment

  • libzmq version (commit hash if unreleased):
    4.2.3 and 4.2.5
  • OS:
    Ubuntu 16.04 and Windows 7

Minimal test code / Steps to reproduce the issue

Running these code, the issue will occur in less than 5 minitues.

server

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "zmq.h"
#ifdef WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#endif

int main() 
{
    int linger = 1000;
    int ret = 0;
    void *ctx = zmq_ctx_new();
    void *conn = zmq_socket(ctx, ZMQ_ROUTER);
    zmq_setsockopt(conn, ZMQ_LINGER, &linger, sizeof(linger));
    ret = zmq_bind(conn, "tcp://*:1026");
    if (-1 == ret) {
        printf("bind failed, errno:%d\n", errno);
        exit(-1);
    }
    zmq_pollitem_t items[1] = { 0 };
    items[0].socket = conn;
    items[0].events = ZMQ_POLLIN;
    while (1) {
        int rc = 0;
        int more = 0;
        size_t more_size = sizeof(more);
        rc = zmq_poll(items, 1, 100);
        if (rc <= 0) {
            if (-1 == rc) {
                printf("zmq_poll failed errno:%d error:%s\n", errno, zmq_strerror(errno));
            }
            continue;
        }
        if (items[0].revents & ZMQ_POLLIN) {
            char ident[128] = { 0 };
            char data[1024] = { 0 };
            int rc = zmq_recv(conn, ident, sizeof(ident), ZMQ_DONTWAIT);
            if (-1 == rc) {
                printf("recv failed errno:%d, error:%s\n", errno, zmq_strerror(errno));
                continue;
            }
            printf("recv ident:%s\n", ident);
            zmq_getsockopt(conn, ZMQ_RCVMORE, &more, &more_size);
            if (!more) {
                printf("there is no more data\n");
                continue;
            }
            zmq_recv(conn, data, sizeof(data), 0);
            printf("recv data:%s\n", data);
            zmq_send(conn, ident, strlen(ident), ZMQ_SNDMORE);
            zmq_send(conn, data, strlen(data) + 1, 0);
        }   
    }
    zmq_close(conn);
    zmq_ctx_term(ctx);
    return 0;
}

client

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>

#include "zmq.h"
#ifdef WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#endif

int main()
{
    char *ident = "123456-hello";
    int linger = 10000;
    int ret = 0;
    char addr[] = "tcp://127.0.0.1:1026";
    void *ctx = zmq_ctx_new();
    void *conn = zmq_socket(ctx, ZMQ_DEALER);
    
    zmq_setsockopt(conn, ZMQ_IDENTITY, ident, strlen(ident));
    zmq_setsockopt(conn, ZMQ_LINGER, &linger, sizeof(linger));
    ret = zmq_connect(conn, addr);
    if (-1 == ret) {
        printf("connnect failed errno:%d error:%s\n", errno, zmq_strerror(errno));
        exit(-1);
    }
    int reconn = 1;
    for (int i=0;;i++) {
        int timeout = 2000;
        char data[256] = { 0 };
        char recv_data[1024] = { 0 };
        if (reconn) {
            zmq_disconnect(conn, addr);
            zmq_connect(conn, addr);
        }
        sprintf(data, "hello world:%d", i);
        ret = zmq_send(conn, data, strlen(data)+1, 0);
        if (ret >= 0) {
            printf("send %s\n", data);
        }
        zmq_setsockopt(conn, ZMQ_RCVTIMEO, &timeout, sizeof(timeout));
        ret = zmq_recv(conn, recv_data, sizeof(recv_data), 0);
        if (ret <= 0) {
            printf("recv failed!!!\n");
            reconn = 0;
        }
        else {
            printf("recv %s\n", recv_data);
        }
        usleep(600*1000);
    }
    
    zmq_close(conn);
    zmq_ctx_term(ctx);
}

What's the actual result? (include assertion message & call stack if applicable)

I can capture the send data using wireshark and the connection state is ESTABLISHIED, but the ZMQ_POLLIN not trigger, .
wireshark-events

What's the expected result?

The ZMQ_POLLIN event will trigger normally.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions