2017-04-13 92 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