0
0
mirror of https://github.com/zeromq/libzmq.git synced 2025-01-14 17:58:01 +08:00

ZMQII-39: Implement IPC transport

This commit is contained in:
Martin Sustrik 2010-01-15 14:11:39 +01:00
parent 56c369272c
commit 2bb57ac57a
24 changed files with 319 additions and 116 deletions

View File

@ -7,7 +7,7 @@ dist_man_MANS = man1/zmq_forwarder.1 man1/zmq_streamer.1 man1/zmq_queue.1 \
man3/zmq_msg_data.3 man3/zmq_msg_size.3 man3/zmq_strerror.3 \ man3/zmq_msg_data.3 man3/zmq_msg_size.3 man3/zmq_strerror.3 \
man7/zmq.7 man7/zmq_cpp.7 man7/zmq_python.7 man7/zmq_ruby.7 \ man7/zmq.7 man7/zmq_cpp.7 man7/zmq_python.7 man7/zmq_ruby.7 \
man7/zmq_cl.7 man7/zmq_tcp.7 man7/zmq_udp.7 man7/zmq_pgm.7 \ man7/zmq_cl.7 man7/zmq_tcp.7 man7/zmq_udp.7 man7/zmq_pgm.7 \
man7/zmq_inproc.7 man7/zmq_inproc.7 man7/zmq_ipc.7
distclean-local: distclean-local:
-rm *.pdf -rm *.pdf

View File

@ -51,4 +51,5 @@ groff -man -Thtml man7/zmq_tcp.7 > man7/zmq_tcp.7.html
groff -man -Thtml man7/zmq_udp.7 > man7/zmq_udp.7.html groff -man -Thtml man7/zmq_udp.7 > man7/zmq_udp.7.html
groff -man -Thtml man7/zmq_pgm.7 > man7/zmq_pgm.7.html groff -man -Thtml man7/zmq_pgm.7 > man7/zmq_pgm.7.html
groff -man -Thtml man7/zmq_inproc.7 > man7/zmq_inproc.7.html groff -man -Thtml man7/zmq_inproc.7 > man7/zmq_inproc.7.html
groff -man -Thtml man7/zmq_ipc.7 > man7/zmq_ipc.7.html

View File

@ -83,4 +83,6 @@ groff -man -Tps man7/zmq_pgm.7 > man7/zmq_pgm.7.ps
ps2pdf man7/zmq_pgm.7.ps zmq_pgm.pdf ps2pdf man7/zmq_pgm.7.ps zmq_pgm.pdf
groff -man -Tps man7/zmq_inproc.7 > man7/zmq_inproc.7.ps groff -man -Tps man7/zmq_inproc.7 > man7/zmq_inproc.7.ps
ps2pdf man7/zmq_inproc.7.ps zmq_inproc.pdf ps2pdf man7/zmq_inproc.7.ps zmq_inproc.pdf
groff -man -Tps man7/zmq_ipc.7 > man7/zmq_ipc.7.ps
ps2pdf man7/zmq_ipc.7.ps zmq_ipc.pdf

View File

@ -112,6 +112,9 @@ UDP reliable multicast transport:
PGM reliable multicast transport: PGM reliable multicast transport:
.BR zmq_pgm(7) .BR zmq_pgm(7)
Inter-process transport:
.BR zmq_ipc (7)
In-process (inter-thread) transport: In-process (inter-thread) transport:
.BR zmq_inproc(7) .BR zmq_inproc(7)

View File

@ -3,7 +3,7 @@
In-process (inter-thread) tranport for 0MQ In-process (inter-thread) tranport for 0MQ
.SH SYNOPSIS .SH SYNOPSIS
In-process transport is optimised for passing messages betweem threads in the In-process transport is optimised for passing messages between threads in the
same process. same process.
Messages are passed directly from one application thread to Messages are passed directly from one application thread to
@ -32,6 +32,7 @@ wire format specification.
.SH "SEE ALSO" .SH "SEE ALSO"
.BR zmq_ipc (7)
.BR zmq_tcp (7) .BR zmq_tcp (7)
.BR zmq_udp (7) .BR zmq_udp (7)
.BR zmq_pgm (7) .BR zmq_pgm (7)

34
man/man7/zmq_ipc.7 Normal file
View File

@ -0,0 +1,34 @@
.TH zmq_ipc 7 "" "(c)2007-2010 iMatix Corporation" "0MQ User Manuals"
.SH NAME
Inter-process tranport for 0MQ
.SH SYNOPSIS
In-process transport is optimised for passing messages between processes on the
same physical machine.
.SH CONNECTION STRING
Connection string for inproc transport is "inproc://" followed by a file name.
The file will be used as placeholder for a message endpoint. (UNIX domain
sockets associate a file with the listening socket in a similar way.)
.nf
ipc:///tmp/my_ipc_endpoint
ipc:///tmp/prices.ipc
.fi
.SH WIRE FORMAT
IPC transport doesn't transfer messages across the network thus there is no need
for a wire format specification.
.SH "SEE ALSO"
.BR zmq_inproc (7)
.BR zmq_tcp (7)
.BR zmq_udp (7)
.BR zmq_pgm (7)
.SH AUTHOR
Martin Sustrik <sustrik at 250bpm dot com>

View File

@ -80,6 +80,7 @@ Following example shows how messages are arranged in subsequent packets:
.BR zmq_udp (7) .BR zmq_udp (7)
.BR zmq_tcp (7) .BR zmq_tcp (7)
.BR zmq_ipc (7)
.BR zmq_inproc (7) .BR zmq_inproc (7)
.BR zmq_setsockopt (3) .BR zmq_setsockopt (3)

View File

@ -72,6 +72,7 @@ Binary layout of a larger message:
.BR zmq_udp (7) .BR zmq_udp (7)
.BR zmq_pgm (7) .BR zmq_pgm (7)
.BR zmq_ipc (7)
.BR zmq_inproc (7) .BR zmq_inproc (7)
.SH AUTHOR .SH AUTHOR

View File

@ -37,6 +37,7 @@ Same as with PGM transport except for UDP packet headers.
.BR zmq_pgm (7) .BR zmq_pgm (7)
.BR zmq_tcp (7) .BR zmq_tcp (7)
.BR zmq_ipc (7)
.BR zmq_inproc (7) .BR zmq_inproc (7)
.SH AUTHOR .SH AUTHOR

View File

@ -309,3 +309,20 @@ int zmq::resolve_ip_hostname (sockaddr_in *addr_, const char *hostname_)
return 0; return 0;
} }
#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS
int zmq::resolve_local_path (sockaddr_un *addr_, const char *path_)
{
if (strlen (path_) >= sizeof (addr_->sun_path))
{
errno = ENAMETOOLONG;
return -1;
}
strcpy (addr_->sun_path, path_);
addr_->sun_family = AF_LOCAL;
return 0;
}
#endif

View File

@ -32,6 +32,10 @@
#include <netdb.h> #include <netdb.h>
#endif #endif
#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS
#include <sys/un.h>
#endif
namespace zmq namespace zmq
{ {
@ -42,6 +46,11 @@ namespace zmq
// This function resolves a string in <hostname>:<port-number> format. // This function resolves a string in <hostname>:<port-number> format.
// Hostname can be either the name of the host or its IP address. // Hostname can be either the name of the host or its IP address.
int resolve_ip_hostname (sockaddr_in *addr_, const char *hostname_); int resolve_ip_hostname (sockaddr_in *addr_, const char *hostname_);
#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS
// This function sets up the sockaddr_un structure with the pathname_
int resolve_local_path( sockaddr_un * addr_, const char* pathname_);
#endif
} }
#endif #endif

View File

@ -87,11 +87,19 @@ int zmq::socket_base_t::bind (const char *addr_)
if (addr_type == "inproc") if (addr_type == "inproc")
return register_endpoint (addr_args.c_str (), this); return register_endpoint (addr_args.c_str (), this);
if (addr_type == "tcp") { if (addr_type == "tcp" || addr_type == "ipc") {
#if defined ZMQ_HAVE_WINDOWS || defined ZMQ_HAVE_OPENVMS
if (addr_type == "ipc") {
errno = EPROTONOSUPPORT;
return -1;
}
#endif
zmq_listener_t *listener = new (std::nothrow) zmq_listener_t ( zmq_listener_t *listener = new (std::nothrow) zmq_listener_t (
choose_io_thread (options.affinity), this, options); choose_io_thread (options.affinity), this, options);
zmq_assert (listener); zmq_assert (listener);
int rc = listener->set_address (addr_args.c_str ()); int rc = listener->set_address (addr_type.c_str(), addr_args.c_str ());
if (rc != 0) if (rc != 0)
return -1; return -1;
@ -202,7 +210,14 @@ int zmq::socket_base_t::connect (const char *addr_)
send_plug (session); send_plug (session);
send_own (this, session); send_own (this, session);
if (addr_type == "tcp") { if (addr_type == "tcp" || addr_type == "ipc") {
#if defined ZMQ_HAVE_WINDOWS || defined ZMQ_HAVE_OPENVMS
if (addr_type == "ipc") {
errno = EPROTONOSUPPORT;
return -1;
}
#endif
// Create the connecter object. Supply it with the session name // Create the connecter object. Supply it with the session name
// so that it can bind the new connection to the session once // so that it can bind the new connection to the session once
@ -211,7 +226,7 @@ int zmq::socket_base_t::connect (const char *addr_)
choose_io_thread (options.affinity), this, options, choose_io_thread (options.affinity), this, options,
session->get_ordinal (), false); session->get_ordinal (), false);
zmq_assert (connecter); zmq_assert (connecter);
int rc = connecter->set_address (addr_args.c_str ()); int rc = connecter->set_address (addr_type.c_str(), addr_args.c_str ());
if (rc != 0) { if (rc != 0) {
delete connecter; delete connecter;
return -1; return -1;

View File

@ -17,6 +17,8 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <string.h>
#include <string> #include <string>
#include "tcp_connecter.hpp" #include "tcp_connecter.hpp"
@ -38,10 +40,13 @@ zmq::tcp_connecter_t::~tcp_connecter_t ()
close (); close ();
} }
int zmq::tcp_connecter_t::set_address (const char *addr_) int zmq::tcp_connecter_t::set_address (const char *protocol_, const char *addr_)
{ {
// Convert the hostname into sockaddr_in structure. if (strcmp (protocol_, "tcp") == 0)
return resolve_ip_hostname (&addr, addr_); return resolve_ip_hostname ((sockaddr_in*) &addr, addr_);
errno = EPROTONOSUPPORT;
return -1;
} }
int zmq::tcp_connecter_t::open () int zmq::tcp_connecter_t::open ()
@ -67,7 +72,7 @@ int zmq::tcp_connecter_t::open ()
wsa_assert (rc != SOCKET_ERROR); wsa_assert (rc != SOCKET_ERROR);
// Connect to the remote peer. // Connect to the remote peer.
rc = ::connect (s, (sockaddr*) &addr, sizeof addr); rc = ::connect (s, (sockaddr*) &addr, sizeof (sockaddr_in));
// Connect was successfull immediately. // Connect was successfull immediately.
if (rc == 0) if (rc == 0)
@ -143,58 +148,94 @@ zmq::tcp_connecter_t::~tcp_connecter_t ()
close (); close ();
} }
int zmq::tcp_connecter_t::set_address (const char *addr_) int zmq::tcp_connecter_t::set_address (const char *protocol_, const char *addr_)
{ {
// Convert the hostname into sockaddr_in structure. if (strcmp (protocol_, "tcp") == 0)
return resolve_ip_hostname (&addr, addr_); return resolve_ip_hostname ((struct sockaddr_in*)&addr, addr_);
else if (strcmp (protocol_, "ipc") == 0)
return resolve_local_path (( struct sockaddr_un*)&addr, addr_);
errno = EPROTONOSUPPORT;
return -1;
} }
int zmq::tcp_connecter_t::open () int zmq::tcp_connecter_t::open ()
{ {
zmq_assert (s == retired_fd); zmq_assert (s == retired_fd);
struct sockaddr *sa = (struct sockaddr*) &addr;
// Create the socket. if (AF_INET == sa->sa_family) {
s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s == -1)
return -1;
// Set to non-blocking mode. // Create the socket.
int flags = fcntl (s, F_GETFL, 0); s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (flags == -1) if (s == -1)
flags = 0; return -1;
int rc = fcntl (s, F_SETFL, flags | O_NONBLOCK);
errno_assert (rc != -1);
// Disable Nagle's algorithm. // Set to non-blocking mode.
int flag = 1; int flags = fcntl (s, F_GETFL, 0);
rc = setsockopt (s, IPPROTO_TCP, TCP_NODELAY, (char*) &flag, sizeof (int)); if (flags == -1)
errno_assert (rc == 0); flags = 0;
int rc = fcntl (s, F_SETFL, flags | O_NONBLOCK);
errno_assert (rc != -1);
// Disable Nagle's algorithm.
int flag = 1;
rc = setsockopt (s, IPPROTO_TCP, TCP_NODELAY, (char*) &flag, sizeof (int));
errno_assert (rc == 0);
#ifdef ZMQ_HAVE_OPENVMS #ifdef ZMQ_HAVE_OPENVMS
// Disable delayed acknowledgements. // Disable delayed acknowledgements.
flag = 1; flag = 1;
rc = setsockopt (s, IPPROTO_TCP, TCP_NODELACK, (char*) &flag, sizeof (int)); rc = setsockopt (s, IPPROTO_TCP, TCP_NODELACK, (char*) &flag, sizeof (int));
errno_assert (rc != SOCKET_ERROR); errno_assert (rc != SOCKET_ERROR);
#endif #endif
// Connect to the remote peer. // Connect to the remote peer.
rc = ::connect (s, (sockaddr*) &addr, sizeof (addr)); rc = ::connect (s, (struct sockaddr*) &addr, sizeof (sockaddr_in));
// Connect was successfull immediately. // Connect was successfull immediately.
if (rc == 0) if (rc == 0)
return 0; return 0;
// Asynchronous connect was launched. // Asynchronous connect was launched.
if (rc == -1 && errno == EINPROGRESS) { if (rc == -1 && errno == EINPROGRESS) {
errno = EAGAIN; errno = EAGAIN;
return -1;
}
// Error occured.
int err = errno;
close ();
errno = err;
return -1;
}
else if (AF_LOCAL == sa->sa_family) {
s = socket (AF_LOCAL, SOCK_STREAM, 0);
if (s == -1)
return -1;
// Set the non-blocking flag.
int flag = fcntl (s, F_GETFL, 0);
if (flag == -1)
flag = 0;
int rc = fcntl (s, F_SETFL, flag | O_NONBLOCK);
errno_assert (rc != -1);
// Connect to the remote peer.
rc = ::connect (s, (struct sockaddr*) &addr, sizeof (sockaddr_un));
// Connect was successfull immediately.
if (rc == 0)
return 0;
// Error occured.
int err = errno;
close ();
errno = err;
return -1; return -1;
} }
// Error occured. zmq_assert (false);
int err = errno;
close ();
errno = err;
return -1;
} }
int zmq::tcp_connecter_t::close () int zmq::tcp_connecter_t::close ()

View File

@ -35,8 +35,8 @@ namespace zmq
tcp_connecter_t (); tcp_connecter_t ();
~tcp_connecter_t (); ~tcp_connecter_t ();
// Set IP address/port to connect to. // Set address to connect to.
int set_address (const char *addr_); int set_address (const char *protocol, const char *addr_);
// Open TCP connecting socket. Address is in // Open TCP connecting socket. Address is in
// <hostname>:<port-number> format. Returns -1 in case of error, // <hostname>:<port-number> format. Returns -1 in case of error,

View File

@ -39,10 +39,16 @@ zmq::tcp_listener_t::~tcp_listener_t ()
close (); close ();
} }
int zmq::tcp_listener_t::set_address (const char *addr_) int zmq::tcp_listener_t::set_address (cosnt char *protocol_, const char *addr_)
{ {
// IPC protocol is not supported on Windows platform.
if (strcmp (protocol_, "tcp") != 0 ) {
errno = EPROTONOSUPPORT;
return -1;
}
// Convert the interface into sockaddr_in structure. // Convert the interface into sockaddr_in structure.
int rc = resolve_ip_interface (&addr, addr_); int rc = resolve_ip_interface ((sockaddr_in*) &addr, addr_);
if (rc != 0) if (rc != 0)
return rc; return rc;
@ -65,7 +71,7 @@ int zmq::tcp_listener_t::set_address (const char *addr_)
wsa_assert (rc != SOCKET_ERROR); wsa_assert (rc != SOCKET_ERROR);
// Bind the socket to the network interface and port. // Bind the socket to the network interface and port.
rc = bind (s, (struct sockaddr*) &addr, sizeof (addr)); rc = bind (s, (struct sockaddr*) &addr, sizeof (sockaddr_in));
if (rc == SOCKET_ERROR) { if (rc == SOCKET_ERROR) {
wsa_error_to_errno (); wsa_error_to_errno ();
return -1; return -1;
@ -131,6 +137,7 @@ zmq::fd_t zmq::tcp_listener_t::accept ()
#include <netinet/in.h> #include <netinet/in.h>
#include <netdb.h> #include <netdb.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/un.h>
zmq::tcp_listener_t::tcp_listener_t () : zmq::tcp_listener_t::tcp_listener_t () :
s (retired_fd) s (retired_fd)
@ -144,45 +151,91 @@ zmq::tcp_listener_t::~tcp_listener_t ()
close (); close ();
} }
int zmq::tcp_listener_t::set_address (const char *addr_) int zmq::tcp_listener_t::set_address (const char *protocol_, const char *addr_)
{ {
// Convert the interface into sockaddr_in structure. if (strcmp (protocol_, "tcp") == 0 ) {
int rc = resolve_ip_interface (&addr, addr_);
if (rc != 0)
return rc;
// Create a listening socket. // Convert the interface into sockaddr_in structure.
s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); int rc = resolve_ip_interface ((struct sockaddr_in*) &addr, addr_);
if (s == -1) if (rc != 0)
return -1; return -1;
// Allow reusing of the address. // Create a listening socket.
int flag = 1; s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
rc = setsockopt (s, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof (int)); if (s == -1)
errno_assert (rc == 0); return -1;
// Set the non-blocking flag. // Allow reusing of the address.
flag = fcntl (s, F_GETFL, 0); int flag = 1;
if (flag == -1) rc = setsockopt (s, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof (int));
flag = 0; errno_assert (rc == 0);
rc = fcntl (s, F_SETFL, flag | O_NONBLOCK);
errno_assert (rc != -1);
// Bind the socket to the network interface and port. // Set the non-blocking flag.
rc = bind (s, (struct sockaddr*) &addr, sizeof (addr)); flag = fcntl (s, F_GETFL, 0);
if (rc != 0) { if (flag == -1)
close (); flag = 0;
return -1; rc = fcntl (s, F_SETFL, flag | O_NONBLOCK);
} errno_assert (rc != -1);
// Listen for incomming connections. // Bind the socket to the network interface and port.
rc = listen (s, tcp_connection_backlog); rc = bind (s, (struct sockaddr*) &addr, sizeof (sockaddr_in));
if (rc != 0) { if (rc != 0) {
close (); close ();
return -1; return -1;
}
// Listen for incomming connections.
rc = listen (s, tcp_connection_backlog);
if (rc != 0) {
close ();
return -1;
}
return 0;
} }
else if (strcmp (protocol_, "ipc") == 0) {
return 0; // Get rid of the file associated with the UNIX domain socket that
// may have been left behind by the previous run of the application.
::unlink (addr_);
// Convert the address into sockaddr_un structure.
int rc = resolve_local_path ((struct sockaddr_un*) &addr, addr_);
if (rc != 0)
return -1;
// Create a listening socket.
s = socket (AF_LOCAL, SOCK_STREAM, 0);
if (s == -1)
return -1;
// Set the non-blocking flag.
int flag = fcntl (s, F_GETFL, 0);
if (flag == -1)
flag = 0;
rc = fcntl (s, F_SETFL, flag | O_NONBLOCK);
errno_assert (rc != -1);
// Bind the socket to the file path.
rc = bind (s, (struct sockaddr*) &addr, sizeof (sockaddr_un));
if (rc != 0) {
close ();
return -1;
}
// Listen for incomming connections.
rc = listen (s, tcp_connection_backlog);
if (rc != 0) {
close ();
return -1;
}
return 0;
}
else {
errno = EPROTONOSUPPORT;
return -1;
}
} }
int zmq::tcp_listener_t::close () int zmq::tcp_listener_t::close ()
@ -192,6 +245,17 @@ int zmq::tcp_listener_t::close ()
if (rc != 0) if (rc != 0)
return -1; return -1;
s = retired_fd; s = retired_fd;
// If there's an underlying UNIX domain socket, get rid of the file it
// is associated with.
struct sockaddr *sa = (struct sockaddr*) &addr;
if (AF_LOCAL == sa->sa_family) {
struct sockaddr_un *sun = (struct sockaddr_un*) &addr;
rc = ::unlink(sun->sun_path);
if (rc != 0)
return -1;
}
return 0; return 0;
} }
@ -239,19 +303,23 @@ zmq::fd_t zmq::tcp_listener_t::accept ()
int rc = fcntl (sock, F_SETFL, flags | O_NONBLOCK); int rc = fcntl (sock, F_SETFL, flags | O_NONBLOCK);
errno_assert (rc != -1); errno_assert (rc != -1);
// Disable Nagle's algorithm. struct sockaddr *sa = (struct sockaddr*) &addr;
int flag = 1; if (AF_INET == sa->sa_family) {
rc = setsockopt (sock, IPPROTO_TCP, TCP_NODELAY, (char*) &flag,
sizeof (int)); // Disable Nagle's algorithm.
errno_assert (rc == 0); int flag = 1;
rc = setsockopt (sock, IPPROTO_TCP, TCP_NODELAY, (char*) &flag,
sizeof (int));
errno_assert (rc == 0);
#ifdef ZMQ_HAVE_OPENVMS #ifdef ZMQ_HAVE_OPENVMS
// Disable delayed acknowledgements. // Disable delayed acknowledgements.
flag = 1; flag = 1;
rc = setsockopt (sock, IPPROTO_TCP, TCP_NODELACK, (char*) &flag, rc = setsockopt (sock, IPPROTO_TCP, TCP_NODELACK, (char*) &flag,
sizeof (int)); sizeof (int));
errno_assert (rc != SOCKET_ERROR); errno_assert (rc != SOCKET_ERROR);
#endif #endif
}
return sock; return sock;
} }

View File

@ -35,10 +35,8 @@ namespace zmq
tcp_listener_t (); tcp_listener_t ();
~tcp_listener_t (); ~tcp_listener_t ();
// Start listening on the interface. Address is in // Start listening on the interface.
// <interface-name>:<port-number> format. Interface name may be '*' int set_address (const char *protocol_, const char *addr_);
// to bind to all the interfaces.
int set_address (const char *addr_);
// Close the listening socket. // Close the listening socket.
int close (); int close ();
@ -54,8 +52,8 @@ namespace zmq
private: private:
// IP address/port to listen on. // Address to listen on.
sockaddr_in addr; sockaddr_storage addr;
// Underlying socket. // Underlying socket.
fd_t s; fd_t s;

View File

@ -41,11 +41,13 @@ zmq::zmq_connecter_t::~zmq_connecter_t ()
{ {
} }
int zmq::zmq_connecter_t::set_address (const char *address_) int zmq::zmq_connecter_t::set_address (const char *protocol_,
const char *address_)
{ {
int rc = tcp_connecter.set_address (address_); int rc = tcp_connecter.set_address (protocol_, address_);
if (rc != 0) if (rc != 0)
return rc; return rc;
protocol = protocol_;
address = address_; address = address_;
return 0; return 0;
} }
@ -91,7 +93,8 @@ void zmq::zmq_connecter_t::out_event ()
// Create an init object. // Create an init object.
zmq_init_t *init = new (std::nothrow) zmq_init_t ( zmq_init_t *init = new (std::nothrow) zmq_init_t (
choose_io_thread (options.affinity), owner, choose_io_thread (options.affinity), owner,
fd, options, true, address.c_str (), session_ordinal); fd, options, true, protocol.c_str (), address.c_str (),
session_ordinal);
zmq_assert (init); zmq_assert (init);
send_plug (init); send_plug (init);
send_own (owner, init); send_own (owner, init);
@ -128,7 +131,6 @@ void zmq::zmq_connecter_t::start_connecting ()
} }
// Handle any other error condition by eventual reconnect. // Handle any other error condition by eventual reconnect.
tcp_connecter.close ();
wait = true; wait = true;
add_timer (); add_timer ();
} }

View File

@ -39,8 +39,8 @@ namespace zmq
const options_t &options_, uint64_t session_ordinal_, bool wait_); const options_t &options_, uint64_t session_ordinal_, bool wait_);
~zmq_connecter_t (); ~zmq_connecter_t ();
// Set IP address to connect to. // Set address to connect to.
int set_address (const char *address_); int set_address (const char *protocol_, const char *address_);
private: private:
@ -75,7 +75,8 @@ namespace zmq
// Associated socket options. // Associated socket options.
options_t options; options_t options;
// Address to connect to. // Protocol and address to connect to.
std::string protocol;
std::string address; std::string address;
zmq_connecter_t (const zmq_connecter_t&); zmq_connecter_t (const zmq_connecter_t&);

View File

@ -27,7 +27,8 @@
#include "err.hpp" #include "err.hpp"
zmq::zmq_engine_t::zmq_engine_t (io_thread_t *parent_, fd_t fd_, zmq::zmq_engine_t::zmq_engine_t (io_thread_t *parent_, fd_t fd_,
const options_t &options_, bool reconnect_, const char *address_) : const options_t &options_, bool reconnect_,
const char *protocol_, const char *address_) :
io_object_t (parent_), io_object_t (parent_),
inpos (NULL), inpos (NULL),
insize (0), insize (0),
@ -39,8 +40,10 @@ zmq::zmq_engine_t::zmq_engine_t (io_thread_t *parent_, fd_t fd_,
options (options_), options (options_),
reconnect (reconnect_) reconnect (reconnect_)
{ {
if (reconnect) if (reconnect) {
protocol = protocol_;
address = address_; address = address_;
}
// Initialise the underlying socket. // Initialise the underlying socket.
int rc = tcp_socket.open (fd_, options.sndbuf, options.rcvbuf); int rc = tcp_socket.open (fd_, options.sndbuf, options.rcvbuf);
@ -166,7 +169,7 @@ void zmq::zmq_engine_t::error ()
inout->get_io_thread (), inout->get_owner (), inout->get_io_thread (), inout->get_owner (),
options, inout->get_ordinal (), true); options, inout->get_ordinal (), true);
zmq_assert (reconnecter); zmq_assert (reconnecter);
reconnecter->set_address (address.c_str ()); reconnecter->set_address (protocol.c_str(), address.c_str ());
} }
inout->detach (reconnecter); inout->detach (reconnecter);

View File

@ -22,6 +22,8 @@
#include <stddef.h> #include <stddef.h>
#include <string>
#include "i_engine.hpp" #include "i_engine.hpp"
#include "io_object.hpp" #include "io_object.hpp"
#include "tcp_socket.hpp" #include "tcp_socket.hpp"
@ -37,7 +39,8 @@ namespace zmq
public: public:
zmq_engine_t (class io_thread_t *parent_, fd_t fd_, zmq_engine_t (class io_thread_t *parent_, fd_t fd_,
const options_t &options_, bool reconnect_, const char *address_); const options_t &options_, bool reconnect_,
const char *protocol_, const char *address_);
~zmq_engine_t (); ~zmq_engine_t ();
// i_engine interface implementation. // i_engine interface implementation.
@ -70,6 +73,7 @@ namespace zmq
options_t options; options_t options;
bool reconnect; bool reconnect;
std::string protocol;
std::string address; std::string address;
zmq_engine_t (const zmq_engine_t&); zmq_engine_t (const zmq_engine_t&);

View File

@ -25,7 +25,7 @@
zmq::zmq_init_t::zmq_init_t (io_thread_t *parent_, socket_base_t *owner_, zmq::zmq_init_t::zmq_init_t (io_thread_t *parent_, socket_base_t *owner_,
fd_t fd_, const options_t &options_, bool reconnect_, fd_t fd_, const options_t &options_, bool reconnect_,
const char *address_, uint64_t session_ordinal_) : const char *protocol_, const char *address_, uint64_t session_ordinal_) :
owned_t (parent_, owner_), owned_t (parent_, owner_),
sent (false), sent (false),
received (false), received (false),
@ -34,7 +34,7 @@ zmq::zmq_init_t::zmq_init_t (io_thread_t *parent_, socket_base_t *owner_,
{ {
// Create the engine object for this connection. // Create the engine object for this connection.
engine = new (std::nothrow) zmq_engine_t (parent_, fd_, options, engine = new (std::nothrow) zmq_engine_t (parent_, fd_, options,
reconnect_, address_); reconnect_, protocol_, address_);
zmq_assert (engine); zmq_assert (engine);
} }

View File

@ -41,7 +41,8 @@ namespace zmq
zmq_init_t (class io_thread_t *parent_, socket_base_t *owner_, zmq_init_t (class io_thread_t *parent_, socket_base_t *owner_,
fd_t fd_, const options_t &options_, bool reconnect_, fd_t fd_, const options_t &options_, bool reconnect_,
const char *address_, uint64_t session_ordinal_); const char *protocol_, const char *address_,
uint64_t session_ordinal_);
~zmq_init_t (); ~zmq_init_t ();
private: private:

View File

@ -36,9 +36,9 @@ zmq::zmq_listener_t::~zmq_listener_t ()
{ {
} }
int zmq::zmq_listener_t::set_address (const char *addr_) int zmq::zmq_listener_t::set_address (const char *protocol_, const char *addr_)
{ {
return tcp_listener.set_address (addr_); return tcp_listener.set_address (protocol_, addr_);
} }
void zmq::zmq_listener_t::process_plug () void zmq::zmq_listener_t::process_plug ()
@ -65,7 +65,7 @@ void zmq::zmq_listener_t::in_event ()
// Create an init object. // Create an init object.
io_thread_t *io_thread = choose_io_thread (options.affinity); io_thread_t *io_thread = choose_io_thread (options.affinity);
zmq_init_t *init = new (std::nothrow) zmq_init_t ( zmq_init_t *init = new (std::nothrow) zmq_init_t (
io_thread, owner, fd, options, false, NULL, 0); io_thread, owner, fd, options, false, NULL, NULL, 0);
zmq_assert (init); zmq_assert (init);
send_plug (init); send_plug (init);
send_own (owner, init); send_own (owner, init);

View File

@ -36,8 +36,8 @@ namespace zmq
zmq_listener_t (class io_thread_t *parent_, socket_base_t *owner_, zmq_listener_t (class io_thread_t *parent_, socket_base_t *owner_,
const options_t &options_); const options_t &options_);
// Set IP address to listen on. // Set address to listen on.
int set_address (const char *addr_); int set_address (const char* protocol_, const char *addr_);
private: private: