Rust, libzmq, клиент отправляет сообщение только при последующем получении

#rust #zeromq

Вопрос:

Я тестирую клиент Rust libzmq

https://crates.io/crates/libzmq

https://docs.rs/libzmq/0.2.5/libzmq/struct.ClientBuilder.html

и наткнулся на это странное поведение.

Этот клиент не стал бы отправлять сообщение:

 use libzmq::{prelude::*, *, ServerBuilder, ClientBuilder, TcpAddr};

fn main() -> Result<(), String> {
    
    let saddr = format!("{}:{}", "192.168.1.206","5540");
    println!("Strating client for {}", saddr);
    let addr2: TcpAddr = saddr.try_into().unwrap();
    
    let client = ClientBuilder::new()
        .connect(amp;addr2)
        .build().unwrap();
    client.send("test").unwrap();

    println!("Finished");
    Ok(())
}
 

это пошло бы:

 use libzmq::{prelude::*, *, ServerBuilder, ClientBuilder, TcpAddr};

fn main() -> Result<(), String> {
    
    let saddr = format!("{}:{}", "192.168.1.206","5540");
    println!("Strating client for {}", saddr);
    let addr2: TcpAddr = saddr.try_into().unwrap();
    
    let client = ClientBuilder::new()
        .connect(amp;addr2)
        .build().unwrap();
    client.send("test").unwrap();

    let mut msg = Msg::new();
    client.recv(amp;mut msg).unwrap();

    println!("Finished");
    Ok(())
}
 

Для получения я использую сервер python (но я также тестировал на Rust).:

 import zmq
if __name__ == '__main__':

    context = zmq.Context()
    socket = context.socket(zmq.SERVER)
    socket.bind("tcp://0.0.0.0:5540")
    print("waiting for hand shake")
    m = socket.recv(copy=False)
    print("got it...")
    socket.send(b'READY', routing_id=m.routing_id)
    print("sent reply")
    socket.close()
    context.term()
 

Вывод на стороне сервера из кода 1:

 waiting for hand shake
[blocked]
 

Вывод на стороне сервера из кода 2:

 waiting for hand shake
got it...
sent reply
 

использование этой версии для Rust:

 [dependencies]
libzmq = "0.2.5"
 

Ответ №1:

libzmq Ящик-это просто оболочка для libzmq библиотеки Си. В документации к библиотеке C вы найдете это примечание:

ПРИМЕЧАНИЕ. Успешный вызов функции zmq_msg_send() не указывает на то, что сообщение было передано в сеть, только на то, что оно было поставлено в очередь в «сокете», и 0MQ взял на себя ответственность за сообщение.

В вашем первом примере, поскольку программа завершает работу сразу после вызова send , сообщение все еще находится в libzmq очереди и еще не было передано. Во втором примере сообщение передается, пока ваша программа ожидает recv вызова.