2017-04-13 96 views
1

我正在恢复生成一个基于zeromq的三年期项目。EAGAIN在zeromq上收到REQ/REP而没有阻塞套接字

在编写代码(在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: connect failed with error 11 (Resource temporarily unavailable)

和第二个(Python)的服务器上生成此错误:

E: socket error number 11 (Resource temporarily unavailable)

但客户端收到的回复。

这是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++之间有这样的区别。

UPDATE:

正如指出通过@詹姆斯哈维,此代码的工作...:

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绑定建造,测试或错误号捕捉异常是一样的。其实它不是。

回答

1

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

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

+0

好吧,你是完全正确的。此代码的工作原理如下: 尝试std :: cout <<“正在连接...”<< std :: endl; client-> connect(server_name.c_str()); zmq :: message_t request(5); memcpy(请求。data(),“Hello”,5); std :: cout <<“发送Hello”<< std :: endl; client-> send(request); (std :: exception&e){std :: exception&e){std :: cout <<“E:connect failed with error”<< e.what()<< std :: endl; } – d3k