-
Notifications
You must be signed in to change notification settings - Fork 787
Description
During a port of a project from Centos 7 to Windows 10, I discovered some inconsistent behavior when connecting to a socket using a wildcard address and port. In the client code I manually connected to the port provided by the server code using 0.0.0.0 and no communication occurs, change the string to using localhost and the sockets communicate as expected.
This seems to be a problem that was already seen in libzmq zeromq/libzmq#1920 and persists in cppzmq or at least in version 4.7.1 provided by vcpkg. While its not a huge problem it does mean windows code is required to parse out the port from socket.get(zmq::sockopt::last_endpoint) and change the connection string to use localhost or 127.0.0.1 with out any indicator of what the problem is.
Modified Client and Server code to replicate behavior:
//
// Hello World client in C++
// Connects REQ socket to tcp://localhost:5555
// Sends "Hello" to server, expects "World" back
//
#include <zmq.hpp>
#include <string>
#include <iostream>
int main ()
{
// Prepare our context and socket
zmq::context_t context (1);
zmq::socket_t socket (context, zmq::socket_type::req);
std::cout << "Connecting to hello world server..." << std::endl;
// Manually change address to port provided by server
socket.connect ("tcp://0.0.0.0:59474");
// Do 10 requests, waiting each time for a response
for (int request_nbr = 0; request_nbr != 10; request_nbr++) {
zmq::message_t request (5);
memcpy (request.data (), "Hello", 5);
std::cout << "Sending Hello " << request_nbr << "..." << std::endl;
socket.send (request, zmq::send_flags::none);
// Get the reply.
zmq::message_t reply;
socket.recv (reply, zmq::recv_flags::none);
std::cout << "Received World " << request_nbr << std::endl;
}
return 0;
}
//
// Hello World server in C++
// Binds REP socket to tcp://*:5555
// Expects "Hello" from client, replies with "World"
//
#include <zmq.hpp>
#include <string>
#include <iostream>
#ifndef _WIN32
#include <unistd.h>
#else
#include <windows.h>
#define sleep(n) Sleep(n)
#endif
int main () {
// Prepare our context and socket
zmq::context_t context (2);
zmq::socket_t socket (context, zmq::socket_type::rep);
socket.bind ("tcp://*:*");
while (true) {
zmq::message_t request;
// Print out actual address for client to use
std::cout << socket.get(zmq::sockopt::last_endpoint) << std::endl;
// Wait for next request from client
socket.recv (request, zmq::recv_flags::none);
std::cout << "Received Hello" << std::endl;
// Do some 'work'
sleep(1);
// Send reply back to client
zmq::message_t reply (5);
memcpy (reply.data (), "World", 5);
socket.send (reply, zmq::send_flags::none);
}
return 0;
}