Search code examples
c++network-programmingzeromqtelnet

0MQ telnet data C++


I'm trying to get working sending telnet commands with 0MQ with C++ on VS2013.

I used HW client sample code from ZMQ hompage.

But what I see on WireShark is telnet packet with no data inside.

This code is prototype, what I need is just to be able to send this command.

After making it work, it will get some cleaning.

//
//  Hello World client in C++
//  Connects REQ socket to tcp://localhost:5555
//  Sends "Hello" to server, expects "World" back
//
#include <zmq.hpp>
#include <zmq.h>
#include <string>
#include <iostream>

int main()
{
    //  Prepare our context and socket
    zmq::context_t context(1);
    zmq::socket_t socket(context, ZMQ_REQ);

    std::cout << "Connecting to hello world server…" << std::endl;
    socket.connect("tcp://10.40.6.226:23");

    //  Do 10 requests, waiting each time for a response
    for (int request_nbr = 0; request_nbr != 1; request_nbr++) {
        zmq::message_t request(2);
        memcpy(request.data(), "Hello", 5);
        std::cout << "Sending Hello " << request_nbr << "…" << std::endl;
        socket.send(request);
        //client_socket

        //  Get the reply.
        /*zmq::message_t reply;
        socket.recv(&reply);
        std::cout << "Received World " << request_nbr << std::endl;*/
    }
    return 0;
}

So everything looks good beside I'm cannot see the string "Hello" in telnet packet.

Original sample http://zguide.zeromq.org/cpp:hwclient


Solution

  • Yes, one can send telnet commands over ZeroMQ

    There is no principal obstacle in doing this. Once you correctly setup the end-to-end relation over ZeroMQ, your telnet-commands may smoothly flow across the link, meeting all the required underlying protocol-specific handshaking and event-handling.

    Why it does not work here?

    The strongest reason "behind" the observed scenario is, that you have missed the essence of the ZeroMQ Formal Communication Patterns framework.

    ZeroMQ sockets are not "plain"-sockets as might the re-use of the word socket remind. There would be close to none benefit if ZeroMQ would just mimick a dumb-socket already available from the operating system. The greatest intellectual value one may benefit from ZeroMQ is based right on the opposite approach. Thanks to a several thousands man*years of experience that were put into the birth of AQMP and ZeroMQ & their younger ancestors, there are smart features built-in the framework which we are happy to re-use in our application domains, rather than trying to re-invent the wheel again.

    The best next step?

    Supposing one's interest in smart messaging is not lost, the best next step IMHO is to spend one's time on reading a great book "Code Connected, Vol.1" from Pieter HINTJENS, a co-father of the ZeroMQ >>> https://stackoverflow.com/a/25742744/3666197


    + a minor note, why the code does not move any data over a wire

    A good design practice brought into the ZeroMQ architecture, have separated a transport per-se from the connection-state of a socket-archetype. That said, one may "pump-data-into" a local end of a-socket-archetype ( your code .send()-s 10x in a for loop ) but a remote-end need not be online throughout that whole episode ( or at all ). This means, the PHY-layer ( the wire ) will see and transport any data if-and-only-if both endo-points of the Formal Communication Pattern agree to do so.

    In the REQ/REP scenario that means

    1. {REQ|REP}.bind() <-online-visibility-episode-> {REP|REQ}.connect() state
    2. REQ.send()-> REP.recv()
    3. REP.send()-> ( REQ.recv())
    4. REQ.send()->

    keeping the nature of the Merry-Go-Round policy of the REQ/REP Formal Communication Pattern "forward-stepping".

    In the posted for(){...} code-block this means that if step 1. is met you may wire-detect just the first and the only one message from REQ to REP, as you seem not to take care to perform mandatory steps 2. & 3. to .recv() a response from REP before the REQ-behavioural model will allow to send any next request ( which is the core nature of the REQ/REP pattern, isn't it? ).

    Once your ZeroMQ insight gets farther, you would also get used to check errors associated with respective function calls.

    Invoking a .connect() attempt, directed ( fortunately over port 23 ) to the hands of a telnet-daemon will be visible on a wire-level, however a protocol-level handshaking would hardly allow a correctly formulated ZeroMQ-wire-level protocol message ( which will for sure surprise the wire-level sniffer if in non-transparent mode ( assuming a telnet ) ) to make happy the telnet-daemon process, which is waiting for nothing else but a telnet-protocol-session setup dialogue, which in described scenario simply must fail to get met.