EAGAIN在zeromq REQ / REP上收到而没有阻塞套接字

时间:2017-04-13 09:28:03

标签: python c++ zeromq

我正在恢复生活在zeromq上建立的一个为期三年的项目。

在编写代码时(在ubuntu 14.04上),代码正在工作(据我所知)。现在(ubuntu 16.04和libzmq.so.5)代码编译但是zeromq通信出了问题,这让我发疯了。

zeromq部分是由我编写的,所以我非常了解代码,也许这就是我无法看到错误的原因。

服务器端代码非常复杂,但我尝试坚持相关部分:

WorkerServer::WorkerServer(){
    address="tcp://*:4321";
    justreceived=-1;
    bind();
}

void WorkerServer::bind(){
    actual_socket=server_socket();
    actual_socket->bind(address.c_str());
    std::cout << "I: server listening on " << address.c_str() << std::endl ;
}

static zmq::socket_t* server_socket(){
    static zmq::context_t context(1);
    return new zmq::socket_t(context, ZMQ_REP);
}

初始化后,服务器启动一个无限循环,调用这些代码行:

int rc=actual_socket->recv(&message);
if(rc!=0){
    std::cout << "E: socket error number " << errno << " (" << zmq_strerror(errno) << ")" << std::endl;
}else{
    std::cout << "I: received message" << std::endl ;
}

当我第一次编译时,我开始收到EAGAIN错误,但没有任何工作。 所以,我写了两个简单的客户端,第一个用C ++编写,第二个用Python编写。

第一个(C ++)在客户端上生成 这个错误:

  

E:连接失败,错误11(资源暂时不可用)

而第二个(Python)在服务器上生成 这个错误:

  

E:套接字错误号11(资源暂时不可用)

但客户实际上收到回复。

这是python代码:

#!/usr/bin/python

import zmq
import sys

port = "4321"    
context = zmq.Context()
print "Connecting to server..."
socket = context.socket(zmq.REQ)
socket.connect ("tcp://localhost:%s" % port)
if len(sys.argv) > 2:
    socket.connect ("tcp://localhost:%s" % port1)

#  Do 10 requests, waiting each time for a response
for request in range (1,10):
    print "Sending request ", request,"..."
    socket.send ("Hello")
    #  Get the reply.
    message = socket.recv()
    print "Received reply ", request, "[", message, "]"

这是c ++代码:

#include <string>
#include <vector>
#include <iostream>
#include "msgpack.hpp"
#include "unistd.h"
#include "cxxabi.h"
#include "zmq.hpp"

main(){

    std::string server_name("tcp://localhost:4321");

    static zmq::context_t context(1);
    std::cout << "I: connecting to server " << server_name << " with context " << (void*)(context) << std::endl;
    zmq::socket_t * client = new zmq::socket_t (context, ZMQ_REQ);
    std::cout << "I: created client " << (void*)(client) << " with errno " << errno << std::endl;
    sleep(1);
    client->connect (server_name.c_str());
    if(errno!=0){
        std::cout << "E: connect failed with error " << errno << " (" << zmq_strerror (errno) << ")" << std::endl;
        exit(1);
    }
}

有什么想法吗?我不明白为什么这不起作用以及为什么python和c ++之间存在这样的差异。

更新:

正如@James Harvey所指出的,这段代码有效......:

try{
        std::cout << "Connecting..." << std::endl;
        client->connect (server_name.c_str());

        zmq::message_t request (5);
        memcpy (request.data (), "Hello", 5);
        std::cout << "Sending Hello " << std::endl;
        client->send (request);
}catch(std::exception& e){
        std::cout << "E: connect failed with error " << e.what() << std::endl;    
}

我在想,因为zmqpp是基于C绑定构建的,所以测试errno或捕获异常是一样的。 实际上,事实并非如此。

1 个答案:

答案 0 :(得分:1)

在您的c ++代码中,您使用的是cppzmq绑定吗?如果是这样,你应该在连接上使用try / catch来查看它是否失败,只有在连接失败时,errno才有效。

https://github.com/zeromq/cppzmq/blob/master/zmq.hpp#L603