Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
L
libzmq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
libzmq
Commits
b60689e5
Commit
b60689e5
authored
Jan 31, 2013
by
Chuck Remes
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #508 from hintjens/master
IPv6 related changes and cleanups to test cases
parents
049931fc
309740e1
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
32 changed files
with
525 additions
and
728 deletions
+525
-728
.gitignore
.gitignore
+1
-0
zmq_getsockopt.txt
doc/zmq_getsockopt.txt
+17
-4
zmq_setsockopt.txt
doc/zmq_setsockopt.txt
+19
-5
zmq.h
include/zmq.h
+2
-1
options.cpp
src/options.cpp
+0
-0
options.hpp
src/options.hpp
+2
-4
socket_base.cpp
src/socket_base.cpp
+1
-1
tcp_address.cpp
src/tcp_address.cpp
+34
-43
tcp_address.hpp
src/tcp_address.hpp
+6
-9
tcp_listener.cpp
src/tcp_listener.cpp
+4
-3
test_connect_delay.cpp
tests/test_connect_delay.cpp
+89
-112
test_connect_resolve.cpp
tests/test_connect_resolve.cpp
+2
-4
test_disconnect_inproc.cpp
tests/test_disconnect_inproc.cpp
+11
-23
test_hwm.cpp
tests/test_hwm.cpp
+6
-5
test_invalid_rep.cpp
tests/test_invalid_rep.cpp
+5
-4
test_last_endpoint.cpp
tests/test_last_endpoint.cpp
+14
-6
test_monitor.cpp
tests/test_monitor.cpp
+73
-83
test_msg_flags.cpp
tests/test_msg_flags.cpp
+14
-8
test_pair_inproc.cpp
tests/test_pair_inproc.cpp
+2
-4
test_pair_ipc.cpp
tests/test_pair_ipc.cpp
+2
-4
test_pair_tcp.cpp
tests/test_pair_tcp.cpp
+2
-4
test_raw_sock.cpp
tests/test_raw_sock.cpp
+97
-210
test_reqrep_device.cpp
tests/test_reqrep_device.cpp
+6
-8
test_reqrep_inproc.cpp
tests/test_reqrep_inproc.cpp
+2
-4
test_reqrep_ipc.cpp
tests/test_reqrep_ipc.cpp
+2
-4
test_reqrep_tcp.cpp
tests/test_reqrep_tcp.cpp
+2
-4
test_router_mandatory.cpp
tests/test_router_mandatory.cpp
+36
-56
test_shutdown_stress.cpp
tests/test_shutdown_stress.cpp
+3
-5
test_sub_forward.cpp
tests/test_sub_forward.cpp
+13
-15
test_term_endpoint.cpp
tests/test_term_endpoint.cpp
+16
-22
test_timeo.cpp
tests/test_timeo.cpp
+40
-71
testutil.hpp
tests/testutil.hpp
+2
-2
No files found.
.gitignore
View file @
b60689e5
...
@@ -42,6 +42,7 @@ tests/test_connect_resolve
...
@@ -42,6 +42,7 @@ tests/test_connect_resolve
tests/test_connect_delay
tests/test_connect_delay
tests/test_term_endpoint
tests/test_term_endpoint
tests/test_router_mandatory
tests/test_router_mandatory
tests/test_disconnect_inproc
tests/test_raw_sock
tests/test_raw_sock
tests/test_disconnect_inproc
tests/test_disconnect_inproc
src/platform.hpp*
src/platform.hpp*
...
...
doc/zmq_getsockopt.txt
View file @
b60689e5
...
@@ -324,12 +324,24 @@ Default value:: -1 (infinite)
...
@@ -324,12 +324,24 @@ Default value:: -1 (infinite)
Applicable socket types:: all
Applicable socket types:: all
ZMQ_IPV6: Retrieve IPv6 socket status
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Retrieve the IPv6 option for the socket. A value of `1` means IPv6 is
enabled on the socket, while `0` means the socket will use only IPv4.
When IPv6 is enabled the socket will connect to, or accept connections
from, both IPv4 and IPv6 hosts.
[horizontal]
Option value type:: int
Option value unit:: boolean
Default value:: 0 (false)
Applicable socket types:: all, when using TCP transports.
ZMQ_IPV4ONLY: Retrieve IPv4-only socket override status
ZMQ_IPV4ONLY: Retrieve IPv4-only socket override status
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Retrieve the underlying native socket type. A value of `1` will use IPv4
Retrieve the IPv4-only option for the socket. This option is deprecated.
sockets, while the value of `0` will use IPv6 sockets. An IPv6 socket
Please use the ZMQ_IPV6 option.
lets applications connect to and accept connections from both IPv4 and IPv6
hosts.
[horizontal]
[horizontal]
Option value type:: int
Option value type:: int
...
@@ -470,6 +482,7 @@ Option value unit:: -1,>0
...
@@ -470,6 +482,7 @@ Option value unit:: -1,>0
Default value:: -1 (leave to OS default)
Default value:: -1 (leave to OS default)
Applicable socket types:: all, when using TCP transports.
Applicable socket types:: all, when using TCP transports.
RETURN VALUE
RETURN VALUE
------------
------------
The _zmq_getsockopt()_ function shall return zero if successful. Otherwise it
The _zmq_getsockopt()_ function shall return zero if successful. Otherwise it
...
...
doc/zmq_setsockopt.txt
View file @
b60689e5
...
@@ -342,12 +342,26 @@ Default value:: -1 (infinite)
...
@@ -342,12 +342,26 @@ Default value:: -1 (infinite)
Applicable socket types:: all
Applicable socket types:: all
ZMQ_IPV
4ONLY: Use IPv4-only sockets
ZMQ_IPV
6: Enable IPv6 on socket
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Sets the underlying native socket type. A value of `1` will use IPv4 sockets,
Set the IPv6 option for the socket. A value of `1` means IPv6 is
while the value of `0` will use IPv6 sockets. An IPv6 socket lets
enabled on the socket, while `0` means the socket will use only IPv4.
applications connect to and accept connections from both IPv4 and IPv6 hosts.
When IPv6 is enabled the socket will connect to, or accept connections
from, both IPv4 and IPv6 hosts.
[horizontal]
Option value type:: int
Option value unit:: boolean
Default value:: 0 (false)
Applicable socket types:: all, when using TCP transports.
ZMQ_IPV4ONLY: Use IPv4-only on socket
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Set the IPv4-only ootion for the socket. This option is deprecated.
Please use the ZMQ_IPV6 option.
[horizontal]
[horizontal]
Option value type:: int
Option value type:: int
...
...
include/zmq.h
View file @
b60689e5
...
@@ -241,7 +241,7 @@ ZMQ_EXPORT int zmq_msg_set (zmq_msg_t *msg, int option, int optval);
...
@@ -241,7 +241,7 @@ ZMQ_EXPORT int zmq_msg_set (zmq_msg_t *msg, int option, int optval);
#define ZMQ_MULTICAST_HOPS 25
#define ZMQ_MULTICAST_HOPS 25
#define ZMQ_RCVTIMEO 27
#define ZMQ_RCVTIMEO 27
#define ZMQ_SNDTIMEO 28
#define ZMQ_SNDTIMEO 28
#define ZMQ_IPV4ONLY 31
#define ZMQ_IPV4ONLY 31
/* Request replacement by IPV6 */
#define ZMQ_LAST_ENDPOINT 32
#define ZMQ_LAST_ENDPOINT 32
#define ZMQ_ROUTER_MANDATORY 33
#define ZMQ_ROUTER_MANDATORY 33
#define ZMQ_TCP_KEEPALIVE 34
#define ZMQ_TCP_KEEPALIVE 34
...
@@ -252,6 +252,7 @@ ZMQ_EXPORT int zmq_msg_set (zmq_msg_t *msg, int option, int optval);
...
@@ -252,6 +252,7 @@ ZMQ_EXPORT int zmq_msg_set (zmq_msg_t *msg, int option, int optval);
#define ZMQ_DELAY_ATTACH_ON_CONNECT 39
#define ZMQ_DELAY_ATTACH_ON_CONNECT 39
#define ZMQ_XPUB_VERBOSE 40
#define ZMQ_XPUB_VERBOSE 40
#define ZMQ_ROUTER_RAW 41
#define ZMQ_ROUTER_RAW 41
#define ZMQ_IPV6 42
/* Message options */
/* Message options */
...
...
src/options.cpp
View file @
b60689e5
This diff is collapsed.
Click to expand it.
src/options.hpp
View file @
b60689e5
...
@@ -92,10 +92,8 @@ namespace zmq
...
@@ -92,10 +92,8 @@ namespace zmq
int
rcvtimeo
;
int
rcvtimeo
;
int
sndtimeo
;
int
sndtimeo
;
// If 1, indicates the use of IPv4 sockets only, it will not be
// If true, IPv6 is enabled (as well as IPv4)
// possible to communicate with IPv6-only hosts. If 0, the socket can
bool
ipv6
;
// connect to and accept connections from both IPv4 and IPv6 hosts.
int
ipv4only
;
// If 1, connecting pipes are not attached immediately, meaning a send()
// If 1, connecting pipes are not attached immediately, meaning a send()
// on a socket with only connecting pipes would block
// on a socket with only connecting pipes would block
...
...
src/socket_base.cpp
View file @
b60689e5
...
@@ -499,7 +499,7 @@ int zmq::socket_base_t::connect (const char *addr_)
...
@@ -499,7 +499,7 @@ int zmq::socket_base_t::connect (const char *addr_)
paddr
->
resolved
.
tcp_addr
=
new
(
std
::
nothrow
)
tcp_address_t
();
paddr
->
resolved
.
tcp_addr
=
new
(
std
::
nothrow
)
tcp_address_t
();
alloc_assert
(
paddr
->
resolved
.
tcp_addr
);
alloc_assert
(
paddr
->
resolved
.
tcp_addr
);
int
rc
=
paddr
->
resolved
.
tcp_addr
->
resolve
(
int
rc
=
paddr
->
resolved
.
tcp_addr
->
resolve
(
address
.
c_str
(),
false
,
options
.
ipv
4only
?
true
:
false
);
address
.
c_str
(),
false
,
options
.
ipv
6
);
if
(
rc
!=
0
)
{
if
(
rc
!=
0
)
{
delete
paddr
;
delete
paddr
;
return
-
1
;
return
-
1
;
...
...
src/tcp_address.cpp
View file @
b60689e5
...
@@ -52,10 +52,10 @@
...
@@ -52,10 +52,10 @@
#include <stdlib.h>
#include <stdlib.h>
// On Solaris platform, network interface name can be queried by ioctl.
// On Solaris platform, network interface name can be queried by ioctl.
int
zmq
::
tcp_address_t
::
resolve_nic_name
(
const
char
*
nic_
,
bool
ipv
4only
_
)
int
zmq
::
tcp_address_t
::
resolve_nic_name
(
const
char
*
nic_
,
bool
ipv
6
_
)
{
{
// TODO: Unused parameter, IPv6 support not implemented for Solaris.
// TODO: Unused parameter, IPv6 support not implemented for Solaris.
(
void
)
ipv
4only
_
;
(
void
)
ipv
6
_
;
// Create a socket.
// Create a socket.
int
fd
=
open_socket
(
AF_INET
,
SOCK_DGRAM
,
0
);
int
fd
=
open_socket
(
AF_INET
,
SOCK_DGRAM
,
0
);
...
@@ -106,7 +106,6 @@ int zmq::tcp_address_t::resolve_nic_name (const char *nic_, bool ipv4only_)
...
@@ -106,7 +106,6 @@ int zmq::tcp_address_t::resolve_nic_name (const char *nic_, bool ipv4only_)
errno
=
ENODEV
;
errno
=
ENODEV
;
return
-
1
;
return
-
1
;
}
}
return
0
;
return
0
;
}
}
...
@@ -117,10 +116,10 @@ int zmq::tcp_address_t::resolve_nic_name (const char *nic_, bool ipv4only_)
...
@@ -117,10 +116,10 @@ int zmq::tcp_address_t::resolve_nic_name (const char *nic_, bool ipv4only_)
#include <sys/ioctl.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <net/if.h>
int
zmq
::
tcp_address_t
::
resolve_nic_name
(
const
char
*
nic_
,
bool
ipv
4only
_
)
int
zmq
::
tcp_address_t
::
resolve_nic_name
(
const
char
*
nic_
,
bool
ipv
6
_
)
{
{
// TODO: Unused parameter, IPv6 support not implemented for AIX or HP/UX.
// TODO: Unused parameter, IPv6 support not implemented for AIX or HP/UX.
(
void
)
ipv
4only
_
;
(
void
)
ipv
6
_
;
// Create a socket.
// Create a socket.
int
sd
=
open_socket
(
AF_INET
,
SOCK_DGRAM
,
0
);
int
sd
=
open_socket
(
AF_INET
,
SOCK_DGRAM
,
0
);
...
@@ -141,7 +140,6 @@ int zmq::tcp_address_t::resolve_nic_name (const char *nic_, bool ipv4only_)
...
@@ -141,7 +140,6 @@ int zmq::tcp_address_t::resolve_nic_name (const char *nic_, bool ipv4only_)
errno
=
ENODEV
;
errno
=
ENODEV
;
return
-
1
;
return
-
1
;
}
}
memcpy
(
&
address
.
ipv4
.
sin_addr
,
&
((
sockaddr_in
*
)
&
ifr
.
ifr_addr
)
->
sin_addr
,
memcpy
(
&
address
.
ipv4
.
sin_addr
,
&
((
sockaddr_in
*
)
&
ifr
.
ifr_addr
)
->
sin_addr
,
sizeof
(
in_addr
));
sizeof
(
in_addr
));
...
@@ -157,10 +155,10 @@ int zmq::tcp_address_t::resolve_nic_name (const char *nic_, bool ipv4only_)
...
@@ -157,10 +155,10 @@ int zmq::tcp_address_t::resolve_nic_name (const char *nic_, bool ipv4only_)
// On these platforms, network interface name can be queried
// On these platforms, network interface name can be queried
// using getifaddrs function.
// using getifaddrs function.
int
zmq
::
tcp_address_t
::
resolve_nic_name
(
const
char
*
nic_
,
bool
ipv
4only
_
)
int
zmq
::
tcp_address_t
::
resolve_nic_name
(
const
char
*
nic_
,
bool
ipv
6
_
)
{
{
// Get the addresses.
// Get the addresses.
ifaddrs
*
ifa
=
NULL
;
ifaddrs
*
ifa
=
NULL
;
int
rc
=
getifaddrs
(
&
ifa
);
int
rc
=
getifaddrs
(
&
ifa
);
errno_assert
(
rc
==
0
);
errno_assert
(
rc
==
0
);
zmq_assert
(
ifa
!=
NULL
);
zmq_assert
(
ifa
!=
NULL
);
...
@@ -173,11 +171,8 @@ int zmq::tcp_address_t::resolve_nic_name (const char *nic_, bool ipv4only_)
...
@@ -173,11 +171,8 @@ int zmq::tcp_address_t::resolve_nic_name (const char *nic_, bool ipv4only_)
continue
;
continue
;
int
family
=
ifp
->
ifa_addr
->
sa_family
;
int
family
=
ifp
->
ifa_addr
->
sa_family
;
if
((
family
==
AF_INET
||
(
ipv6_
&&
family
==
AF_INET6
))
if
((
family
==
AF_INET
&&
!
strcmp
(
nic_
,
ifp
->
ifa_name
))
{
||
(
!
ipv4only_
&&
family
==
AF_INET6
))
&&
!
strcmp
(
nic_
,
ifp
->
ifa_name
))
{
memcpy
(
&
address
,
ifp
->
ifa_addr
,
memcpy
(
&
address
,
ifp
->
ifa_addr
,
(
family
==
AF_INET
)
?
sizeof
(
struct
sockaddr_in
)
(
family
==
AF_INET
)
?
sizeof
(
struct
sockaddr_in
)
:
sizeof
(
struct
sockaddr_in6
));
:
sizeof
(
struct
sockaddr_in6
));
...
@@ -193,7 +188,6 @@ int zmq::tcp_address_t::resolve_nic_name (const char *nic_, bool ipv4only_)
...
@@ -193,7 +188,6 @@ int zmq::tcp_address_t::resolve_nic_name (const char *nic_, bool ipv4only_)
errno
=
ENODEV
;
errno
=
ENODEV
;
return
-
1
;
return
-
1
;
}
}
return
0
;
return
0
;
}
}
...
@@ -201,11 +195,11 @@ int zmq::tcp_address_t::resolve_nic_name (const char *nic_, bool ipv4only_)
...
@@ -201,11 +195,11 @@ int zmq::tcp_address_t::resolve_nic_name (const char *nic_, bool ipv4only_)
// On other platforms we assume there are no sane interface names.
// On other platforms we assume there are no sane interface names.
// This is true especially of Windows.
// This is true especially of Windows.
int
zmq
::
tcp_address_t
::
resolve_nic_name
(
const
char
*
nic_
,
bool
ipv
4only
_
)
int
zmq
::
tcp_address_t
::
resolve_nic_name
(
const
char
*
nic_
,
bool
ipv
6
_
)
{
{
// All unused parameters.
// All unused parameters.
(
void
)
nic_
;
(
void
)
nic_
;
(
void
)
ipv
4only
_
;
(
void
)
ipv
6
_
;
errno
=
ENODEV
;
errno
=
ENODEV
;
return
-
1
;
return
-
1
;
...
@@ -213,8 +207,7 @@ int zmq::tcp_address_t::resolve_nic_name (const char *nic_, bool ipv4only_)
...
@@ -213,8 +207,7 @@ int zmq::tcp_address_t::resolve_nic_name (const char *nic_, bool ipv4only_)
#endif
#endif
int
zmq
::
tcp_address_t
::
resolve_interface
(
const
char
*
interface_
,
int
zmq
::
tcp_address_t
::
resolve_interface
(
const
char
*
interface_
,
bool
ipv6_
)
bool
ipv4only_
)
{
{
// Initialize temporary output pointers with storage address.
// Initialize temporary output pointers with storage address.
sockaddr_storage
ss
;
sockaddr_storage
ss
;
...
@@ -223,15 +216,7 @@ int zmq::tcp_address_t::resolve_interface (const char *interface_,
...
@@ -223,15 +216,7 @@ int zmq::tcp_address_t::resolve_interface (const char *interface_,
// Initialise IP-format family/port and populate temporary output pointers
// Initialise IP-format family/port and populate temporary output pointers
// with the address.
// with the address.
if
(
ipv4only_
)
{
if
(
ipv6_
)
{
sockaddr_in
ip4_addr
;
memset
(
&
ip4_addr
,
0
,
sizeof
(
ip4_addr
));
ip4_addr
.
sin_family
=
AF_INET
;
ip4_addr
.
sin_addr
.
s_addr
=
htonl
(
INADDR_ANY
);
out_addrlen
=
sizeof
ip4_addr
;
memcpy
(
out_addr
,
&
ip4_addr
,
out_addrlen
);
}
else
{
sockaddr_in6
ip6_addr
;
sockaddr_in6
ip6_addr
;
memset
(
&
ip6_addr
,
0
,
sizeof
(
ip6_addr
));
memset
(
&
ip6_addr
,
0
,
sizeof
(
ip6_addr
));
ip6_addr
.
sin6_family
=
AF_INET6
;
ip6_addr
.
sin6_family
=
AF_INET6
;
...
@@ -239,8 +224,15 @@ int zmq::tcp_address_t::resolve_interface (const char *interface_,
...
@@ -239,8 +224,15 @@ int zmq::tcp_address_t::resolve_interface (const char *interface_,
out_addrlen
=
sizeof
ip6_addr
;
out_addrlen
=
sizeof
ip6_addr
;
memcpy
(
out_addr
,
&
ip6_addr
,
out_addrlen
);
memcpy
(
out_addr
,
&
ip6_addr
,
out_addrlen
);
}
}
else
{
// * resolves to INADDR_ANY or in6addr_any.
sockaddr_in
ip4_addr
;
memset
(
&
ip4_addr
,
0
,
sizeof
(
ip4_addr
));
ip4_addr
.
sin_family
=
AF_INET
;
ip4_addr
.
sin_addr
.
s_addr
=
htonl
(
INADDR_ANY
);
out_addrlen
=
sizeof
ip4_addr
;
memcpy
(
out_addr
,
&
ip4_addr
,
out_addrlen
);
}
// "*" resolves to INADDR_ANY or in6addr_any.
if
(
strcmp
(
interface_
,
"*"
)
==
0
)
{
if
(
strcmp
(
interface_
,
"*"
)
==
0
)
{
zmq_assert
(
out_addrlen
<=
sizeof
address
);
zmq_assert
(
out_addrlen
<=
sizeof
address
);
memcpy
(
&
address
,
out_addr
,
out_addrlen
);
memcpy
(
&
address
,
out_addr
,
out_addrlen
);
...
@@ -248,7 +240,7 @@ int zmq::tcp_address_t::resolve_interface (const char *interface_,
...
@@ -248,7 +240,7 @@ int zmq::tcp_address_t::resolve_interface (const char *interface_,
}
}
// Try to resolve the string as a NIC name.
// Try to resolve the string as a NIC name.
int
rc
=
resolve_nic_name
(
interface_
,
ipv
4only
_
);
int
rc
=
resolve_nic_name
(
interface_
,
ipv
6
_
);
if
(
rc
!=
0
&&
errno
!=
ENODEV
)
if
(
rc
!=
0
&&
errno
!=
ENODEV
)
return
rc
;
return
rc
;
if
(
rc
==
0
)
if
(
rc
==
0
)
...
@@ -266,7 +258,7 @@ int zmq::tcp_address_t::resolve_interface (const char *interface_,
...
@@ -266,7 +258,7 @@ int zmq::tcp_address_t::resolve_interface (const char *interface_,
// Choose IPv4 or IPv6 protocol family. Note that IPv6 allows for
// Choose IPv4 or IPv6 protocol family. Note that IPv6 allows for
// IPv4-in-IPv6 addresses.
// IPv4-in-IPv6 addresses.
req
.
ai_family
=
ipv
4only_
?
AF_INET
:
AF_INET6
;
req
.
ai_family
=
ipv
6_
?
AF_INET6
:
AF_INET
;
// Arbitrary, not used in the output, but avoids duplicate results.
// Arbitrary, not used in the output, but avoids duplicate results.
req
.
ai_socktype
=
SOCK_STREAM
;
req
.
ai_socktype
=
SOCK_STREAM
;
...
@@ -304,7 +296,7 @@ int zmq::tcp_address_t::resolve_interface (const char *interface_,
...
@@ -304,7 +296,7 @@ int zmq::tcp_address_t::resolve_interface (const char *interface_,
return
0
;
return
0
;
}
}
int
zmq
::
tcp_address_t
::
resolve_hostname
(
const
char
*
hostname_
,
bool
ipv
4only
_
)
int
zmq
::
tcp_address_t
::
resolve_hostname
(
const
char
*
hostname_
,
bool
ipv
6
_
)
{
{
// Set up the query.
// Set up the query.
#if defined ZMQ_HAVE_OPENVMS && defined __ia64 && __INITIAL_POINTER_SIZE == 64
#if defined ZMQ_HAVE_OPENVMS && defined __ia64 && __INITIAL_POINTER_SIZE == 64
...
@@ -316,7 +308,7 @@ int zmq::tcp_address_t::resolve_hostname (const char *hostname_, bool ipv4only_)
...
@@ -316,7 +308,7 @@ int zmq::tcp_address_t::resolve_hostname (const char *hostname_, bool ipv4only_)
// Choose IPv4 or IPv6 protocol family. Note that IPv6 allows for
// Choose IPv4 or IPv6 protocol family. Note that IPv6 allows for
// IPv4-in-IPv6 addresses.
// IPv4-in-IPv6 addresses.
req
.
ai_family
=
ipv
4only_
?
AF_INET
:
AF_INET6
;
req
.
ai_family
=
ipv
6_
?
AF_INET6
:
AF_INET
;
// Need to choose one to avoid duplicate results from getaddrinfo() - this
// Need to choose one to avoid duplicate results from getaddrinfo() - this
// doesn't really matter, since it's not included in the addr-output.
// doesn't really matter, since it's not included in the addr-output.
...
@@ -382,7 +374,7 @@ zmq::tcp_address_t::~tcp_address_t ()
...
@@ -382,7 +374,7 @@ zmq::tcp_address_t::~tcp_address_t ()
{
{
}
}
int
zmq
::
tcp_address_t
::
resolve
(
const
char
*
name_
,
bool
local_
,
bool
ipv
4only
_
)
int
zmq
::
tcp_address_t
::
resolve
(
const
char
*
name_
,
bool
local_
,
bool
ipv
6
_
)
{
{
// Find the ':' at end that separates address from the port number.
// Find the ':' at end that separates address from the port number.
const
char
*
delimiter
=
strrchr
(
name_
,
':'
);
const
char
*
delimiter
=
strrchr
(
name_
,
':'
);
...
@@ -390,7 +382,6 @@ int zmq::tcp_address_t::resolve (const char *name_, bool local_, bool ipv4only_)
...
@@ -390,7 +382,6 @@ int zmq::tcp_address_t::resolve (const char *name_, bool local_, bool ipv4only_)
errno
=
EINVAL
;
errno
=
EINVAL
;
return
-
1
;
return
-
1
;
}
}
// Separate the address/port.
// Separate the address/port.
std
::
string
addr_str
(
name_
,
delimiter
-
name_
);
std
::
string
addr_str
(
name_
,
delimiter
-
name_
);
std
::
string
port_str
(
delimiter
+
1
);
std
::
string
port_str
(
delimiter
+
1
);
...
@@ -400,8 +391,8 @@ int zmq::tcp_address_t::resolve (const char *name_, bool local_, bool ipv4only_)
...
@@ -400,8 +391,8 @@ int zmq::tcp_address_t::resolve (const char *name_, bool local_, bool ipv4only_)
addr_str
[
addr_str
.
size
()
-
1
]
==
']'
)
addr_str
[
addr_str
.
size
()
-
1
]
==
']'
)
addr_str
=
addr_str
.
substr
(
1
,
addr_str
.
size
()
-
2
);
addr_str
=
addr_str
.
substr
(
1
,
addr_str
.
size
()
-
2
);
uint16_t
port
;
// Allow 0 specifically, to detect invalid port error in atoi if not
// Allow 0 specifically, to detect invalid port error in atoi if not
uint16_t
port
;
if
(
port_str
==
"*"
||
port_str
==
"0"
)
if
(
port_str
==
"*"
||
port_str
==
"0"
)
// Resolve wildcard to 0 to allow autoselection of port
// Resolve wildcard to 0 to allow autoselection of port
port
=
0
;
port
=
0
;
...
@@ -417,9 +408,9 @@ int zmq::tcp_address_t::resolve (const char *name_, bool local_, bool ipv4only_)
...
@@ -417,9 +408,9 @@ int zmq::tcp_address_t::resolve (const char *name_, bool local_, bool ipv4only_)
// Resolve the IP address.
// Resolve the IP address.
int
rc
;
int
rc
;
if
(
local_
)
if
(
local_
)
rc
=
resolve_interface
(
addr_str
.
c_str
(),
ipv
4only
_
);
rc
=
resolve_interface
(
addr_str
.
c_str
(),
ipv
6
_
);
else
else
rc
=
resolve_hostname
(
addr_str
.
c_str
(),
ipv
4only
_
);
rc
=
resolve_hostname
(
addr_str
.
c_str
(),
ipv
6
_
);
if
(
rc
!=
0
)
if
(
rc
!=
0
)
return
-
1
;
return
-
1
;
...
@@ -434,7 +425,8 @@ int zmq::tcp_address_t::resolve (const char *name_, bool local_, bool ipv4only_)
...
@@ -434,7 +425,8 @@ int zmq::tcp_address_t::resolve (const char *name_, bool local_, bool ipv4only_)
int
zmq
::
tcp_address_t
::
to_string
(
std
::
string
&
addr_
)
int
zmq
::
tcp_address_t
::
to_string
(
std
::
string
&
addr_
)
{
{
if
(
address
.
generic
.
sa_family
!=
AF_INET
&&
address
.
generic
.
sa_family
!=
AF_INET6
)
{
if
(
address
.
generic
.
sa_family
!=
AF_INET
&&
address
.
generic
.
sa_family
!=
AF_INET6
)
{
addr_
.
clear
();
addr_
.
clear
();
return
-
1
;
return
-
1
;
}
}
...
@@ -493,7 +485,7 @@ int zmq::tcp_address_mask_t::mask () const
...
@@ -493,7 +485,7 @@ int zmq::tcp_address_mask_t::mask () const
return
address_mask
;
return
address_mask
;
}
}
int
zmq
::
tcp_address_mask_t
::
resolve
(
const
char
*
name_
,
bool
ipv
4only
_
)
int
zmq
::
tcp_address_mask_t
::
resolve
(
const
char
*
name_
,
bool
ipv
6
_
)
{
{
// Find '/' at the end that separates address from the cidr mask number.
// Find '/' at the end that separates address from the cidr mask number.
// Allow empty mask clause and threat it like '/32' for ipv4 or '/128' for ipv6.
// Allow empty mask clause and threat it like '/32' for ipv4 or '/128' for ipv6.
...
@@ -507,12 +499,11 @@ int zmq::tcp_address_mask_t::resolve (const char *name_, bool ipv4only_)
...
@@ -507,12 +499,11 @@ int zmq::tcp_address_mask_t::resolve (const char *name_, bool ipv4only_)
return
-
1
;
return
-
1
;
}
}
}
}
else
{
else
addr_str
.
assign
(
name_
);
addr_str
.
assign
(
name_
);
}
// Parse address part using standard routines.
// Parse address part using standard routines.
int
rc
=
tcp_address_t
::
resolve_hostname
(
addr_str
.
c_str
(),
ipv
4only
_
);
int
rc
=
tcp_address_t
::
resolve_hostname
(
addr_str
.
c_str
(),
ipv
6
_
);
if
(
rc
!=
0
)
if
(
rc
!=
0
)
return
rc
;
return
rc
;
...
...
src/tcp_address.hpp
View file @
b60689e5
...
@@ -45,8 +45,8 @@ namespace zmq
...
@@ -45,8 +45,8 @@ namespace zmq
// This function translates textual TCP address into an address
// This function translates textual TCP address into an address
// strcuture. If 'local' is true, names are resolved as local interface
// strcuture. If 'local' is true, names are resolved as local interface
// names. If it is false, names are resolved as remote hostnames.
// names. If it is false, names are resolved as remote hostnames.
// If 'ipv
4only' is true, the name will never
resolve to IPv6 address.
// If 'ipv
6' is true, the name may
resolve to IPv6 address.
int
resolve
(
const
char
*
name_
,
bool
local_
,
bool
ipv4only
_
);
int
resolve
(
const
char
*
name_
,
bool
local_
,
bool
ipv6
_
);
// The opposite to resolve()
// The opposite to resolve()
virtual
int
to_string
(
std
::
string
&
addr_
);
virtual
int
to_string
(
std
::
string
&
addr_
);
...
@@ -60,10 +60,9 @@ namespace zmq
...
@@ -60,10 +60,9 @@ namespace zmq
socklen_t
addrlen
()
const
;
socklen_t
addrlen
()
const
;
protected
:
protected
:
int
resolve_nic_name
(
const
char
*
nic_
,
bool
ipv6_
);
int
resolve_nic_name
(
const
char
*
nic_
,
bool
ipv4only_
);
int
resolve_interface
(
const
char
*
interface_
,
bool
ipv6_
);
int
resolve_interface
(
const
char
*
interface_
,
bool
ipv4only_
);
int
resolve_hostname
(
const
char
*
hostname_
,
bool
ipv6_
);
int
resolve_hostname
(
const
char
*
hostname_
,
bool
ipv4only_
);
union
{
union
{
sockaddr
generic
;
sockaddr
generic
;
...
@@ -75,13 +74,12 @@ namespace zmq
...
@@ -75,13 +74,12 @@ namespace zmq
class
tcp_address_mask_t
:
public
tcp_address_t
class
tcp_address_mask_t
:
public
tcp_address_t
{
{
public
:
public
:
tcp_address_mask_t
();
tcp_address_mask_t
();
// This function enhances tcp_address_t::resolve() with ability to parse
// This function enhances tcp_address_t::resolve() with ability to parse
// additional cidr-like(/xx) mask value at the end of the name string.
// additional cidr-like(/xx) mask value at the end of the name string.
// Works only with remote hostnames.
// Works only with remote hostnames.
int
resolve
(
const
char
*
name_
,
bool
ipv4only
_
);
int
resolve
(
const
char
*
name_
,
bool
ipv6
_
);
// The opposite to resolve()
// The opposite to resolve()
int
to_string
(
std
::
string
&
addr_
);
int
to_string
(
std
::
string
&
addr_
);
...
@@ -91,7 +89,6 @@ namespace zmq
...
@@ -91,7 +89,6 @@ namespace zmq
bool
match_address
(
const
struct
sockaddr
*
ss
,
const
socklen_t
ss_len
)
const
;
bool
match_address
(
const
struct
sockaddr
*
ss
,
const
socklen_t
ss_len
)
const
;
private
:
private
:
int
address_mask
;
int
address_mask
;
};
};
...
...
src/tcp_listener.cpp
View file @
b60689e5
...
@@ -148,7 +148,7 @@ int zmq::tcp_listener_t::get_address (std::string &addr_)
...
@@ -148,7 +148,7 @@ int zmq::tcp_listener_t::get_address (std::string &addr_)
int
zmq
::
tcp_listener_t
::
set_address
(
const
char
*
addr_
)
int
zmq
::
tcp_listener_t
::
set_address
(
const
char
*
addr_
)
{
{
// Convert the textual address into address structure.
// Convert the textual address into address structure.
int
rc
=
address
.
resolve
(
addr_
,
true
,
options
.
ipv
4only
?
true
:
false
);
int
rc
=
address
.
resolve
(
addr_
,
true
,
options
.
ipv
6
);
if
(
rc
!=
0
)
if
(
rc
!=
0
)
return
-
1
;
return
-
1
;
...
@@ -160,8 +160,9 @@ int zmq::tcp_listener_t::set_address (const char *addr_)
...
@@ -160,8 +160,9 @@ int zmq::tcp_listener_t::set_address (const char *addr_)
#endif
#endif
// IPv6 address family not supported, try automatic downgrade to IPv4.
// IPv6 address family not supported, try automatic downgrade to IPv4.
if
(
address
.
family
()
==
AF_INET6
&&
errno
==
EAFNOSUPPORT
&&
if
(
address
.
family
()
==
AF_INET6
!
options
.
ipv4only
)
{
&&
errno
==
EAFNOSUPPORT
&&
options
.
ipv6
)
{
rc
=
address
.
resolve
(
addr_
,
true
,
true
);
rc
=
address
.
resolve
(
addr_
,
true
,
true
);
if
(
rc
!=
0
)
if
(
rc
!=
0
)
return
rc
;
return
rc
;
...
...
tests/test_connect_delay.cpp
View file @
b60689e5
/*
/*
Copyright (c) 2012 Ian Barber
Copyright (c) 2012 Ian Barber
Copyright (c) 2012 Other contributors as noted in the AUTHORS file
Copyright (c) 2007-2013 iMatix Corporation
This file is part of 0MQ.
This file is part of 0MQ.
0MQ is free software; you can redistribute it and/or modify it under
0MQ is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by
the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3 of the License, or
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
(at your option) any later version.
0MQ is distributed in the hope that it will be useful,
0MQ is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
You should have received a copy of the GNU Lesser General Public License
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 "../include/zmq.h"
#include "../include/zmq.h"
#include "../include/zmq_utils.h"
#include <errno.h>
#include <errno.h>
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
...
@@ -31,12 +29,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
...
@@ -31,12 +29,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
int
main
(
void
)
int
main
(
void
)
{
{
fprintf
(
stderr
,
"test_connect_delay running...
\n
"
);
int
val
;
int
val
;
int
rc
;
int
rc
;
char
buffer
[
16
];
char
buffer
[
16
];
int
seen
=
0
;
// TEST 1.
// TEST 1.
// First we're going to attempt to send messages to two
// First we're going to attempt to send messages to two
// pipes, one connected, the other not. We should see
// pipes, one connected, the other not. We should see
...
@@ -53,7 +48,7 @@ int main (void)
...
@@ -53,7 +48,7 @@ int main (void)
val
=
0
;
val
=
0
;
rc
=
zmq_setsockopt
(
to
,
ZMQ_LINGER
,
&
val
,
sizeof
(
val
));
rc
=
zmq_setsockopt
(
to
,
ZMQ_LINGER
,
&
val
,
sizeof
(
val
));
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_bind
(
to
,
"tcp://*:6555"
);
rc
=
zmq_bind
(
to
,
"tcp://*:6555"
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
// Create a socket pushing to two endpoints - only 1 message should arrive.
// Create a socket pushing to two endpoints - only 1 message should arrive.
...
@@ -61,36 +56,32 @@ int main (void)
...
@@ -61,36 +56,32 @@ int main (void)
assert
(
from
);
assert
(
from
);
val
=
0
;
val
=
0
;
zmq_setsockopt
(
from
,
ZMQ_LINGER
,
&
val
,
sizeof
(
val
));
zmq_setsockopt
(
from
,
ZMQ_LINGER
,
&
val
,
sizeof
(
val
));
// This pipe will not connect
// This pipe will not connect
rc
=
zmq_connect
(
from
,
"tcp://localhost:5556"
);
rc
=
zmq_connect
(
from
,
"tcp://localhost:5556"
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
// This pipe will
// This pipe will
rc
=
zmq_connect
(
from
,
"tcp://localhost:
5
555"
);
rc
=
zmq_connect
(
from
,
"tcp://localhost:
6
555"
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
// We send 10 messages, 5 should just get stuck in the queue
// We send 10 messages, 5 should just get stuck in the queue
// for the not-yet-connected pipe
// for the not-yet-connected pipe
for
(
int
i
=
0
;
i
<
10
;
++
i
)
for
(
int
i
=
0
;
i
<
10
;
++
i
)
{
{
rc
=
zmq_send
(
from
,
"Hello"
,
5
,
0
);
std
::
string
message
(
"message "
);
assert
(
rc
==
5
);
message
+=
(
'0'
+
i
);
rc
=
zmq_send
(
from
,
message
.
data
(),
message
.
size
(),
0
);
assert
(
rc
>=
0
);
}
}
// Sleep to allow the messages to be delivered
zmq_sleep
(
1
);
// We now consume from the connected pipe
// We now consume from the connected pipe
// - we should see just 5
// - we should see just 5
seen
=
0
;
int
timeout
=
100
;
for
(
int
i
=
0
;
i
<
10
;
++
i
)
rc
=
zmq_setsockopt
(
to
,
ZMQ_RCVTIMEO
,
&
timeout
,
sizeof
(
int
));
{
assert
(
rc
==
0
);
memset
(
&
buffer
,
0
,
sizeof
(
buffer
));
rc
=
zmq_recv
(
to
,
&
buffer
,
sizeof
(
buffer
),
ZMQ_DONTWAIT
);
int
seen
=
0
;
if
(
rc
==
-
1
)
while
(
true
)
{
break
;
rc
=
zmq_recv
(
to
,
&
buffer
,
sizeof
(
buffer
),
0
);
if
(
rc
==
-
1
)
break
;
// Break when we didn't get a message
seen
++
;
seen
++
;
}
}
assert
(
seen
==
5
);
assert
(
seen
==
5
);
...
@@ -112,7 +103,6 @@ int main (void)
...
@@ -112,7 +103,6 @@ int main (void)
// cause the pipe attachment to be delayed until the connection
// cause the pipe attachment to be delayed until the connection
// succeeds.
// succeeds.
context
=
zmq_ctx_new
();
context
=
zmq_ctx_new
();
fprintf
(
stderr
,
" Rerunning with DELAY_ATTACH_ON_CONNECT
\n
"
);
// Bind the valid socket
// Bind the valid socket
to
=
zmq_socket
(
context
,
ZMQ_PULL
);
to
=
zmq_socket
(
context
,
ZMQ_PULL
);
...
@@ -145,26 +135,21 @@ int main (void)
...
@@ -145,26 +135,21 @@ int main (void)
assert
(
rc
==
0
);
assert
(
rc
==
0
);
// Send 10 messages, all should be routed to the connected pipe
// Send 10 messages, all should be routed to the connected pipe
for
(
int
i
=
0
;
i
<
10
;
++
i
)
for
(
int
i
=
0
;
i
<
10
;
++
i
)
{
{
rc
=
zmq_send
(
from
,
"Hello"
,
5
,
0
);
std
::
string
message
(
"message "
);
assert
(
rc
==
5
);
message
+=
(
'0'
+
i
);
rc
=
zmq_send
(
from
,
message
.
data
(),
message
.
size
(),
0
);
assert
(
rc
>=
0
);
}
}
rc
=
zmq_setsockopt
(
to
,
ZMQ_RCVTIMEO
,
&
timeout
,
sizeof
(
int
));
// Sleep to allow the messages to be delivered
assert
(
rc
==
0
);
zmq_sleep
(
1
);
// Send 10 messages, all should arrive.
seen
=
0
;
seen
=
0
;
for
(
int
i
=
0
;
i
<
10
;
++
i
)
while
(
true
)
{
{
rc
=
zmq_recv
(
to
,
&
buffer
,
sizeof
(
buffer
),
0
);
memset
(
&
buffer
,
0
,
sizeof
(
buffer
));
if
(
rc
==
-
1
)
rc
=
zmq_recv
(
to
,
&
buffer
,
sizeof
(
buffer
),
ZMQ_DONTWAIT
);
break
;
// Break when we didn't get a message
// If there is a failed delivery, assert!
seen
++
;
assert
(
rc
!=
-
1
);
}
}
assert
(
seen
==
10
);
rc
=
zmq_close
(
from
);
rc
=
zmq_close
(
from
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
...
@@ -178,83 +163,75 @@ int main (void)
...
@@ -178,83 +163,75 @@ int main (void)
// TEST 3
// TEST 3
// This time we want to validate that the same blocking behaviour
// This time we want to validate that the same blocking behaviour
// occurs with an existing connection that is broken. We will send
// occurs with an existing connection that is broken. We will send
// messa
a
ges to a connected pipe, disconnect and verify the messages
// messages to a connected pipe, disconnect and verify the messages
// block. Then we reconnect and verify messages flow again.
// block. Then we reconnect and verify messages flow again.
context
=
zmq_ctx_new
();
context
=
zmq_ctx_new
();
void
*
context2
=
zmq_ctx_new
();
fprintf
(
stderr
,
" Running DELAY_ATTACH_ON_CONNECT with disconnect
\n
"
);
to
=
zmq_socket
(
context2
,
ZMQ_PULL
);
void
*
backend
=
zmq_socket
(
context
,
ZMQ_DEALER
);
assert
(
to
);
assert
(
backend
);
rc
=
zmq_bind
(
to
,
"tcp://*:5560"
);
void
*
frontend
=
zmq_socket
(
context
,
ZMQ_DEALER
);
assert
(
frontend
);
int
zero
=
0
;
rc
=
zmq_setsockopt
(
backend
,
ZMQ_LINGER
,
&
zero
,
sizeof
(
zero
));
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_setsockopt
(
frontend
,
ZMQ_LINGER
,
&
zero
,
sizeof
(
zero
));
val
=
0
;
rc
=
zmq_setsockopt
(
to
,
ZMQ_LINGER
,
&
val
,
sizeof
(
val
));
assert
(
rc
==
0
);
assert
(
rc
==
0
);
// Create a socket pushing
// Frontend connects to backend using DELAY_ATTACH_ON_CONNECT
from
=
zmq_socket
(
context
,
ZMQ_PUSH
);
int
on
=
1
;
assert
(
from
);
rc
=
zmq_setsockopt
(
frontend
,
ZMQ_DELAY_ATTACH_ON_CONNECT
,
&
on
,
sizeof
(
on
));
val
=
0
;
rc
=
zmq_setsockopt
(
from
,
ZMQ_LINGER
,
&
val
,
sizeof
(
val
));
assert
(
rc
==
0
);
assert
(
rc
==
0
);
val
=
1
;
rc
=
zmq_bind
(
backend
,
"tcp://*:5560"
);
rc
=
zmq_setsockopt
(
from
,
ZMQ_DELAY_ATTACH_ON_CONNECT
,
&
val
,
sizeof
(
val
));
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_connect
(
frontend
,
"tcp://localhost:5560"
);
// Connect to the valid socket socket
rc
=
zmq_connect
(
from
,
"tcp://localhost:5560"
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
// Ping backend to frontend so we know when the connection is up
rc
=
zmq_send
(
backend
,
"Hello"
,
5
,
0
);
assert
(
rc
==
5
);
rc
=
zmq_recv
(
frontend
,
buffer
,
255
,
0
);
assert
(
rc
==
5
);
// Allow connections to stabilise
// Send message from frontend to backend
zmq_sleep
(
1
);
rc
=
zmq_send
(
frontend
,
"Hello"
,
5
,
ZMQ_DONTWAIT
);
assert
(
rc
==
5
);
// Send a message, should succeed
std
::
string
message
(
"message "
);
rc
=
zmq_send
(
from
,
message
.
data
(),
message
.
size
(),
0
);
assert
(
rc
>=
0
);
rc
=
zmq_close
(
to
);
assert
(
rc
==
0
);
rc
=
zmq_c
tx_term
(
context2
);
rc
=
zmq_c
lose
(
backend
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
// Give time to process disconnect
// Give time to process disconnect
zmq_sleep
(
1
);
// There's no way to do this except with a sleep
struct
timespec
t
=
{
0
,
250
*
1000000
};
nanosleep
(
&
t
,
NULL
);
// Send a message, should fail
// Send a message, should fail
rc
=
zmq_send
(
fro
m
,
message
.
data
(),
message
.
size
()
,
ZMQ_DONTWAIT
);
rc
=
zmq_send
(
fro
ntend
,
"Hello"
,
5
,
ZMQ_DONTWAIT
);
assert
(
rc
==
-
1
);
assert
(
rc
==
-
1
);
context2
=
zmq_ctx_new
();
to
=
zmq_socket
(
context2
,
ZMQ_PULL
);
assert
(
to
);
rc
=
zmq_bind
(
to
,
"tcp://*:5560"
);
assert
(
rc
==
0
);
val
=
0
;
// Recreate backend socket
rc
=
zmq_setsockopt
(
to
,
ZMQ_LINGER
,
&
val
,
sizeof
(
val
));
backend
=
zmq_socket
(
context
,
ZMQ_DEALER
);
assert
(
backend
);
rc
=
zmq_setsockopt
(
backend
,
ZMQ_LINGER
,
&
zero
,
sizeof
(
zero
));
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_bind
(
backend
,
"tcp://*:5560"
);
// Allow connections to stabilise
assert
(
rc
==
0
);
zmq_sleep
(
1
);
// Ping backend to frontend so we know when the connection is up
rc
=
zmq_send
(
backend
,
"Hello"
,
5
,
0
);
assert
(
rc
==
5
);
rc
=
zmq_recv
(
frontend
,
buffer
,
255
,
0
);
assert
(
rc
==
5
);
// After the reconnect, should succeed
// After the reconnect, should succeed
rc
=
zmq_send
(
fro
m
,
message
.
data
(),
message
.
size
(),
0
);
rc
=
zmq_send
(
fro
ntend
,
"Hello"
,
5
,
ZMQ_DONTWAIT
);
assert
(
rc
>=
0
);
assert
(
rc
==
5
);
rc
=
zmq_close
(
to
);
rc
=
zmq_close
(
backend
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_close
(
fro
m
);
rc
=
zmq_close
(
fro
ntend
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_ctx_term
(
context
);
rc
=
zmq_ctx_term
(
context
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_ctx_term
(
context2
);
assert
(
rc
==
0
);
}
}
tests/test_connect_resolve.cpp
View file @
b60689e5
...
@@ -27,9 +27,7 @@
...
@@ -27,9 +27,7 @@
int
main
(
void
)
int
main
(
void
)
{
{
fprintf
(
stderr
,
"test_connect_resolve running...
\n
"
);
void
*
ctx
=
zmq_ctx_new
();
void
*
ctx
=
zmq_init
(
1
);
assert
(
ctx
);
assert
(
ctx
);
// Create pair of socket, each with high watermark of 2. Thus the total
// Create pair of socket, each with high watermark of 2. Thus the total
...
@@ -47,7 +45,7 @@ int main (void)
...
@@ -47,7 +45,7 @@ int main (void)
rc
=
zmq_close
(
sock
);
rc
=
zmq_close
(
sock
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_term
(
ctx
);
rc
=
zmq_
ctx_
term
(
ctx
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
return
0
;
return
0
;
...
...
tests/test_disconnect_inproc.cpp
View file @
b60689e5
...
@@ -28,28 +28,26 @@ int main(int argc, char** argv) {
...
@@ -28,28 +28,26 @@ int main(int argc, char** argv) {
size_t
more_size
=
sizeof
(
more
);
size_t
more_size
=
sizeof
(
more
);
int
iteration
=
0
;
int
iteration
=
0
;
while
(
1
)
{
while
(
1
)
{
zmq_pollitem_t
items
[]
=
{
zmq_pollitem_t
items
[]
=
{
{
subSocket
,
0
,
ZMQ_POLLIN
,
0
},
// read publications
{
subSocket
,
0
,
ZMQ_POLLIN
,
0
},
// read publications
{
pubSocket
,
0
,
ZMQ_POLLIN
,
0
},
// read subscriptions
{
pubSocket
,
0
,
ZMQ_POLLIN
,
0
},
// read subscriptions
};
};
zmq_poll
(
items
,
2
,
5
00
);
int
rc
=
zmq_poll
(
items
,
2
,
1
00
);
if
(
items
[
1
].
revents
&
ZMQ_POLLIN
)
{
if
(
items
[
1
].
revents
&
ZMQ_POLLIN
)
{
while
(
1
)
{
while
(
1
)
{
zmq_msg_t
msg
;
zmq_msg_t
msg
;
zmq_msg_init
(
&
msg
);
zmq_msg_init
(
&
msg
);
zmq_msg_recv
(
&
msg
,
pubSocket
,
0
);
zmq_msg_recv
(
&
msg
,
pubSocket
,
0
);
int
msgSize
=
zmq_msg_size
(
&
msg
);
char
*
buffer
=
(
char
*
)
zmq_msg_data
(
&
msg
);
char
*
buffer
=
(
char
*
)
zmq_msg_data
(
&
msg
);
if
(
buffer
[
0
]
==
0
)
{
if
(
buffer
[
0
]
==
0
)
{
assert
(
isSubscribed
);
assert
(
isSubscribed
);
printf
(
"unsubscribing from '%s'
\n
"
,
strndup
(
buffer
+
1
,
msgSize
-
1
));
isSubscribed
=
false
;
isSubscribed
=
false
;
}
else
{
}
else
{
assert
(
!
isSubscribed
);
assert
(
!
isSubscribed
);
printf
(
"subscribing on '%s'
\n
"
,
strndup
(
buffer
+
1
,
msgSize
-
1
));
isSubscribed
=
true
;
isSubscribed
=
true
;
}
}
...
@@ -66,11 +64,6 @@ int main(int argc, char** argv) {
...
@@ -66,11 +64,6 @@ int main(int argc, char** argv) {
zmq_msg_t
msg
;
zmq_msg_t
msg
;
zmq_msg_init
(
&
msg
);
zmq_msg_init
(
&
msg
);
zmq_msg_recv
(
&
msg
,
subSocket
,
0
);
zmq_msg_recv
(
&
msg
,
subSocket
,
0
);
int
msgSize
=
zmq_msg_size
(
&
msg
);
char
*
buffer
=
(
char
*
)
zmq_msg_data
(
&
msg
);
printf
(
"received on subscriber '%s'
\n
"
,
strndup
(
buffer
,
msgSize
));
zmq_getsockopt
(
subSocket
,
ZMQ_RCVMORE
,
&
more
,
&
more_size
);
zmq_getsockopt
(
subSocket
,
ZMQ_RCVMORE
,
&
more
,
&
more_size
);
zmq_msg_close
(
&
msg
);
zmq_msg_close
(
&
msg
);
...
@@ -80,34 +73,29 @@ int main(int argc, char** argv) {
...
@@ -80,34 +73,29 @@ int main(int argc, char** argv) {
}
}
}
}
}
}
if
(
iteration
==
1
)
{
if
(
iteration
==
1
)
{
zmq_connect
(
subSocket
,
"inproc://someInProcDescriptor"
)
&&
printf
(
"zmq_connect: %s
\n
"
,
zmq_strerror
(
errno
));
zmq_connect
(
subSocket
,
"inproc://someInProcDescriptor"
)
&&
printf
(
"zmq_connect: %s
\n
"
,
zmq_strerror
(
errno
));
//zmq_connect(subSocket, "tcp://127.0.0.1:30010") && printf("zmq_connect: %s\n", zmq_strerror(errno));
//zmq_connect(subSocket, "tcp://127.0.0.1:30010") && printf("zmq_connect: %s\n", zmq_strerror(errno));
}
}
if
(
iteration
==
4
)
{
if
(
iteration
==
4
)
{
zmq_disconnect
(
subSocket
,
"inproc://someInProcDescriptor"
)
&&
printf
(
"zmq_disconnect(%d): %s
\n
"
,
errno
,
zmq_strerror
(
errno
));
zmq_disconnect
(
subSocket
,
"inproc://someInProcDescriptor"
)
&&
printf
(
"zmq_disconnect(%d): %s
\n
"
,
errno
,
zmq_strerror
(
errno
));
//zmq_disconnect(subSocket, "tcp://127.0.0.1:30010") && printf("zmq_disconnect: %s\n", zmq_strerror(errno));
//zmq_disconnect(subSocket, "tcp://127.0.0.1:30010") && printf("zmq_disconnect: %s\n", zmq_strerror(errno));
}
}
if
(
iteration
>
4
&&
rc
==
0
)
if
(
iteration
==
10
)
{
break
;
break
;
}
zmq_msg_t
channelEnvlp
;
zmq_msg_t
channelEnvlp
;
ZMQ_PREPARE_STRING
(
channelEnvlp
,
"foo"
,
3
);
ZMQ_PREPARE_STRING
(
channelEnvlp
,
"foo"
,
3
);
zmq_
sendmsg
(
pubSocket
,
&
channelEnvlp
,
ZMQ_SNDMORE
)
>=
0
||
printf
(
"zmq_sendmsg
: %s
\n
"
,
zmq_strerror
(
errno
));
zmq_
msg_send
(
&
channelEnvlp
,
pubSocket
,
ZMQ_SNDMORE
)
>=
0
||
printf
(
"zmq_msg_send
: %s
\n
"
,
zmq_strerror
(
errno
));
zmq_msg_close
(
&
channelEnvlp
)
&&
printf
(
"zmq_msg_close: %s
\n
"
,
zmq_strerror
(
errno
));
zmq_msg_close
(
&
channelEnvlp
)
&&
printf
(
"zmq_msg_close: %s
\n
"
,
zmq_strerror
(
errno
));
zmq_msg_t
message
;
zmq_msg_t
message
;
ZMQ_PREPARE_STRING
(
message
,
"this is foo!"
,
12
);
ZMQ_PREPARE_STRING
(
message
,
"this is foo!"
,
12
);
zmq_
sendmsg
(
pubSocket
,
&
message
,
0
)
>=
0
||
printf
(
"zmq_sendmsg
: %s
\n
"
,
zmq_strerror
(
errno
));
zmq_
msg_send
(
&
message
,
pubSocket
,
0
)
>=
0
||
printf
(
"zmq_msg_send
: %s
\n
"
,
zmq_strerror
(
errno
));
zmq_msg_close
(
&
message
)
&&
printf
(
"zmq_msg_close: %s
\n
"
,
zmq_strerror
(
errno
));
zmq_msg_close
(
&
message
)
&&
printf
(
"zmq_msg_close: %s
\n
"
,
zmq_strerror
(
errno
));
iteration
++
;
iteration
++
;
}
}
assert
(
publicationsReceived
==
3
);
assert
(
publicationsReceived
==
3
);
assert
(
!
isSubscribed
);
assert
(
!
isSubscribed
);
...
...
tests/test_hwm.cpp
View file @
b60689e5
...
@@ -19,14 +19,15 @@
...
@@ -19,14 +19,15 @@
*/
*/
#include "../include/zmq.h"
#include <stdio.h>
#include <stdio.h>
#include "testutil.hpp"
#include <string.h>
#undef NDEBUG
#include <assert.h>
int
main
(
void
)
int
main
(
void
)
{
{
fprintf
(
stderr
,
"test_hwm running...
\n
"
);
void
*
ctx
=
zmq_ctx_new
();
void
*
ctx
=
zmq_init
(
1
);
assert
(
ctx
);
assert
(
ctx
);
// Create pair of socket, each with high watermark of 2. Thus the total
// Create pair of socket, each with high watermark of 2. Thus the total
...
@@ -76,7 +77,7 @@ int main (void)
...
@@ -76,7 +77,7 @@ int main (void)
rc
=
zmq_close
(
sb
);
rc
=
zmq_close
(
sb
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_term
(
ctx
);
rc
=
zmq_
ctx_
term
(
ctx
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
return
0
;
return
0
;
...
...
tests/test_invalid_rep.cpp
View file @
b60689e5
...
@@ -27,15 +27,16 @@
...
@@ -27,15 +27,16 @@
int
main
(
void
)
int
main
(
void
)
{
{
fprintf
(
stderr
,
"test_invalid_rep running...
\n
"
);
// Create REQ/ROUTER wiring.
// Create REQ/ROUTER wiring.
void
*
ctx
=
zmq_
init
(
1
);
void
*
ctx
=
zmq_
ctx_new
(
);
assert
(
ctx
);
assert
(
ctx
);
void
*
router_socket
=
zmq_socket
(
ctx
,
ZMQ_ROUTER
);
void
*
router_socket
=
zmq_socket
(
ctx
,
ZMQ_ROUTER
);
assert
(
router_socket
);
assert
(
router_socket
);
void
*
req_socket
=
zmq_socket
(
ctx
,
ZMQ_REQ
);
void
*
req_socket
=
zmq_socket
(
ctx
,
ZMQ_REQ
);
assert
(
req_socket
);
assert
(
req_socket
);
int
linger
=
0
;
int
linger
=
0
;
int
rc
=
zmq_setsockopt
(
router_socket
,
ZMQ_LINGER
,
&
linger
,
sizeof
(
int
));
int
rc
=
zmq_setsockopt
(
router_socket
,
ZMQ_LINGER
,
&
linger
,
sizeof
(
int
));
assert
(
rc
==
0
);
assert
(
rc
==
0
);
...
@@ -84,7 +85,7 @@ int main (void)
...
@@ -84,7 +85,7 @@ int main (void)
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_close
(
req_socket
);
rc
=
zmq_close
(
req_socket
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_term
(
ctx
);
rc
=
zmq_
ctx_
term
(
ctx
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
return
0
;
return
0
;
...
...
tests/test_last_endpoint.cpp
View file @
b60689e5
...
@@ -29,26 +29,34 @@ static void do_bind_and_verify (void *s, const char *endpoint)
...
@@ -29,26 +29,34 @@ static void do_bind_and_verify (void *s, const char *endpoint)
{
{
int
rc
=
zmq_bind
(
s
,
endpoint
);
int
rc
=
zmq_bind
(
s
,
endpoint
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
char
reported
[
255
];
char
test
[
255
];
size_t
size
=
255
;
size_t
siz
=
255
;
rc
=
zmq_getsockopt
(
s
,
ZMQ_LAST_ENDPOINT
,
reported
,
&
size
);
rc
=
zmq_getsockopt
(
s
,
ZMQ_LAST_ENDPOINT
,
test
,
&
siz
);
assert
(
rc
==
0
&&
strcmp
(
reported
,
endpoint
)
==
0
);
assert
(
rc
==
0
&&
strcmp
(
test
,
endpoint
)
==
0
);
}
}
int
main
(
void
)
int
main
(
void
)
{
{
// Create the infrastructure
// Create the infrastructure
void
*
ctx
=
zmq_
init
(
1
);
void
*
ctx
=
zmq_
ctx_new
(
);
assert
(
ctx
);
assert
(
ctx
);
void
*
sb
=
zmq_socket
(
ctx
,
ZMQ_ROUTER
);
void
*
sb
=
zmq_socket
(
ctx
,
ZMQ_ROUTER
);
assert
(
sb
);
assert
(
sb
);
int
val
=
0
;
int
rc
=
zmq_setsockopt
(
sb
,
ZMQ_LINGER
,
&
val
,
sizeof
(
val
));
assert
(
rc
==
0
);
do_bind_and_verify
(
sb
,
"tcp://127.0.0.1:5560"
);
do_bind_and_verify
(
sb
,
"tcp://127.0.0.1:5560"
);
do_bind_and_verify
(
sb
,
"tcp://127.0.0.1:5561"
);
do_bind_and_verify
(
sb
,
"tcp://127.0.0.1:5561"
);
do_bind_and_verify
(
sb
,
"ipc:///tmp/testep"
);
do_bind_and_verify
(
sb
,
"ipc:///tmp/testep"
);
rc
=
zmq_close
(
sb
);
assert
(
rc
==
0
);
rc
=
zmq_ctx_term
(
ctx
);
assert
(
rc
==
0
);
return
0
;
return
0
;
}
}
tests/test_monitor.cpp
View file @
b60689e5
...
@@ -20,7 +20,6 @@
...
@@ -20,7 +20,6 @@
*/
*/
#include "../include/zmq.h"
#include "../include/zmq.h"
#include "../include/zmq_utils.h"
#include <pthread.h>
#include <pthread.h>
#include <string.h>
#include <string.h>
#include "testutil.hpp"
#include "testutil.hpp"
...
@@ -34,27 +33,27 @@ static int rep_socket_events;
...
@@ -34,27 +33,27 @@ static int rep_socket_events;
const
char
*
addr
;
const
char
*
addr
;
extern
"C"
// REQ socket monitor thread
static
void
*
req_socket_monitor
(
void
*
ctx
)
{
{
// REQ socket monitor thread
zmq_event_t
event
;
static
void
*
req_socket_monitor
(
void
*
ctx
)
int
rc
;
{
zmq_event_t
event
;
void
*
s
=
zmq_socket
(
ctx
,
ZMQ_PAIR
);
int
rc
;
assert
(
s
);
void
*
s
=
zmq_socket
(
ctx
,
ZMQ_PAIR
);
rc
=
zmq_connect
(
s
,
"inproc://monitor.req"
);
assert
(
s
);
assert
(
rc
==
0
);
while
(
true
)
{
rc
=
zmq_connect
(
s
,
"inproc://monitor.req"
);
zmq_msg_t
msg
;
assert
(
rc
==
0
);
zmq_msg_init
(
&
msg
);
while
(
true
)
{
rc
=
zmq_msg_recv
(
&
msg
,
s
,
0
);
zmq_msg_t
msg
;
if
(
rc
==
-
1
&&
zmq_errno
()
==
ETERM
)
zmq_msg_init
(
&
msg
);
break
;
rc
=
zmq_recvmsg
(
s
,
&
msg
,
0
);
assert
(
rc
!=
-
1
);
if
(
rc
==
-
1
&&
zmq_errno
()
==
ETERM
)
break
;
assert
(
rc
!=
-
1
);
memcpy
(
&
event
,
zmq_msg_data
(
&
msg
),
sizeof
(
event
));
memcpy
(
&
event
,
zmq_msg_data
(
&
msg
),
sizeof
(
event
));
switch
(
event
.
event
)
{
switch
(
event
.
event
)
{
case
ZMQ_EVENT_CONNECTED
:
case
ZMQ_EVENT_CONNECTED
:
assert
(
event
.
data
.
connected
.
fd
>
0
);
assert
(
event
.
data
.
connected
.
fd
>
0
);
assert
(
!
strcmp
(
event
.
data
.
connected
.
addr
,
addr
));
assert
(
!
strcmp
(
event
.
data
.
connected
.
addr
,
addr
));
...
@@ -81,34 +80,33 @@ extern "C"
...
@@ -81,34 +80,33 @@ extern "C"
assert
(
!
strcmp
(
event
.
data
.
disconnected
.
addr
,
addr
));
assert
(
!
strcmp
(
event
.
data
.
disconnected
.
addr
,
addr
));
req_socket_events
|=
ZMQ_EVENT_DISCONNECTED
;
req_socket_events
|=
ZMQ_EVENT_DISCONNECTED
;
break
;
break
;
}
}
}
zmq_close
(
s
);
return
NULL
;
}
}
zmq_close
(
s
);
return
NULL
;
}
}
extern
"C"
// 2nd REQ socket monitor thread
static
void
*
req2_socket_monitor
(
void
*
ctx
)
{
{
// 2nd REQ socket monitor thread
zmq_event_t
event
;
static
void
*
req2_socket_monitor
(
void
*
ctx
)
int
rc
;
{
zmq_event_t
event
;
void
*
s
=
zmq_socket
(
ctx
,
ZMQ_PAIR
);
int
rc
;
assert
(
s
);
void
*
s
=
zmq_socket
(
ctx
,
ZMQ_PAIR
);
rc
=
zmq_connect
(
s
,
"inproc://monitor.req2"
);
assert
(
s
);
assert
(
rc
==
0
);
while
(
true
)
{
rc
=
zmq_connect
(
s
,
"inproc://monitor.req2"
);
zmq_msg_t
msg
;
assert
(
rc
==
0
);
zmq_msg_init
(
&
msg
);
while
(
true
)
{
rc
=
zmq_msg_recv
(
&
msg
,
s
,
0
);
zmq_msg_t
msg
;
if
(
rc
==
-
1
&&
zmq_errno
()
==
ETERM
)
zmq_msg_init
(
&
msg
);
break
;
rc
=
zmq_recvmsg
(
s
,
&
msg
,
0
);
assert
(
rc
!=
-
1
);
if
(
rc
==
-
1
&&
zmq_errno
()
==
ETERM
)
break
;
assert
(
rc
!=
-
1
);
memcpy
(
&
event
,
zmq_msg_data
(
&
msg
),
sizeof
(
event
));
memcpy
(
&
event
,
zmq_msg_data
(
&
msg
),
sizeof
(
event
));
switch
(
event
.
event
)
{
switch
(
event
.
event
)
{
case
ZMQ_EVENT_CONNECTED
:
case
ZMQ_EVENT_CONNECTED
:
assert
(
event
.
data
.
connected
.
fd
>
0
);
assert
(
event
.
data
.
connected
.
fd
>
0
);
assert
(
!
strcmp
(
event
.
data
.
connected
.
addr
,
addr
));
assert
(
!
strcmp
(
event
.
data
.
connected
.
addr
,
addr
));
...
@@ -119,35 +117,33 @@ extern "C"
...
@@ -119,35 +117,33 @@ extern "C"
assert
(
!
strcmp
(
event
.
data
.
closed
.
addr
,
addr
));
assert
(
!
strcmp
(
event
.
data
.
closed
.
addr
,
addr
));
req2_socket_events
|=
ZMQ_EVENT_CLOSED
;
req2_socket_events
|=
ZMQ_EVENT_CLOSED
;
break
;
break
;
}
}
}
zmq_close
(
s
);
return
NULL
;
}
}
zmq_close
(
s
);
return
NULL
;
}
}
// REP socket monitor thread
extern
"C"
static
void
*
rep_socket_monitor
(
void
*
ctx
)
{
{
// REP socket monitor thread
zmq_event_t
event
;
static
void
*
rep_socket_monitor
(
void
*
ctx
)
int
rc
;
{
zmq_event_t
event
;
void
*
s
=
zmq_socket
(
ctx
,
ZMQ_PAIR
);
int
rc
;
assert
(
s
);
void
*
s
=
zmq_socket
(
ctx
,
ZMQ_PAIR
);
rc
=
zmq_connect
(
s
,
"inproc://monitor.rep"
);
assert
(
s
);
assert
(
rc
==
0
);
while
(
true
)
{
rc
=
zmq_connect
(
s
,
"inproc://monitor.rep"
);
zmq_msg_t
msg
;
assert
(
rc
==
0
);
zmq_msg_init
(
&
msg
);
while
(
true
)
{
rc
=
zmq_msg_recv
(
&
msg
,
s
,
0
);
zmq_msg_t
msg
;
if
(
rc
==
-
1
&&
zmq_errno
()
==
ETERM
)
zmq_msg_init
(
&
msg
);
break
;
rc
=
zmq_recvmsg
(
s
,
&
msg
,
0
);
assert
(
rc
!=
-
1
);
if
(
rc
==
-
1
&&
zmq_errno
()
==
ETERM
)
break
;
assert
(
rc
!=
-
1
);
memcpy
(
&
event
,
zmq_msg_data
(
&
msg
),
sizeof
(
event
));
memcpy
(
&
event
,
zmq_msg_data
(
&
msg
),
sizeof
(
event
));
switch
(
event
.
event
)
{
switch
(
event
.
event
)
{
case
ZMQ_EVENT_LISTENING
:
case
ZMQ_EVENT_LISTENING
:
assert
(
event
.
data
.
listening
.
fd
>
0
);
assert
(
event
.
data
.
listening
.
fd
>
0
);
assert
(
!
strcmp
(
event
.
data
.
listening
.
addr
,
addr
));
assert
(
!
strcmp
(
event
.
data
.
listening
.
addr
,
addr
));
...
@@ -173,12 +169,11 @@ extern "C"
...
@@ -173,12 +169,11 @@ extern "C"
assert
(
!
strcmp
(
event
.
data
.
disconnected
.
addr
,
addr
));
assert
(
!
strcmp
(
event
.
data
.
disconnected
.
addr
,
addr
));
rep_socket_events
|=
ZMQ_EVENT_DISCONNECTED
;
rep_socket_events
|=
ZMQ_EVENT_DISCONNECTED
;
break
;
break
;
}
zmq_msg_close
(
&
msg
);
}
}
zmq_close
(
s
);
zmq_msg_close
(
&
msg
);
return
NULL
;
}
}
zmq_close
(
s
);
return
NULL
;
}
}
int
main
(
void
)
int
main
(
void
)
...
@@ -192,7 +187,7 @@ int main (void)
...
@@ -192,7 +187,7 @@ int main (void)
addr
=
"tcp://127.0.0.1:5560"
;
addr
=
"tcp://127.0.0.1:5560"
;
// Create the infrastructure
// Create the infrastructure
void
*
ctx
=
zmq_
init
(
1
);
void
*
ctx
=
zmq_
ctx_new
(
);
assert
(
ctx
);
assert
(
ctx
);
// REP socket
// REP socket
...
@@ -230,6 +225,8 @@ int main (void)
...
@@ -230,6 +225,8 @@ int main (void)
rc
=
zmq_connect
(
req
,
addr
);
rc
=
zmq_connect
(
req
,
addr
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
bounce
(
rep
,
req
);
// 2nd REQ socket
// 2nd REQ socket
req2
=
zmq_socket
(
ctx
,
ZMQ_REQ
);
req2
=
zmq_socket
(
ctx
,
ZMQ_REQ
);
assert
(
req2
);
assert
(
req2
);
...
@@ -243,17 +240,13 @@ int main (void)
...
@@ -243,17 +240,13 @@ int main (void)
rc
=
zmq_connect
(
req2
,
addr
);
rc
=
zmq_connect
(
req2
,
addr
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
bounce
(
rep
,
req
);
// Allow a window for socket events as connect can be async
zmq_sleep
(
1
);
// Close the REP socket
// Close the REP socket
rc
=
zmq_close
(
rep
);
rc
=
zmq_close
(
rep
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
// Allow some time for detecting error states
// Allow some time for detecting error states
zmq_sleep
(
1
);
struct
timespec
t
=
{
0
,
250
*
1000000
};
nanosleep
(
&
t
,
NULL
);
// Close the REQ socket
// Close the REQ socket
rc
=
zmq_close
(
req
);
rc
=
zmq_close
(
req
);
...
@@ -263,10 +256,7 @@ int main (void)
...
@@ -263,10 +256,7 @@ int main (void)
rc
=
zmq_close
(
req2
);
rc
=
zmq_close
(
req2
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
// Allow for closed or disconnected events to bubble up
zmq_ctx_term
(
ctx
);
zmq_sleep
(
1
);
zmq_term
(
ctx
);
// Expected REP socket events
// Expected REP socket events
assert
(
rep_socket_events
&
ZMQ_EVENT_LISTENING
);
assert
(
rep_socket_events
&
ZMQ_EVENT_LISTENING
);
...
...
tests/test_msg_flags.cpp
View file @
b60689e5
...
@@ -28,14 +28,18 @@
...
@@ -28,14 +28,18 @@
int
main
(
void
)
int
main
(
void
)
{
{
// Create the infrastructure
// Create the infrastructure
void
*
ctx
=
zmq_
init
(
0
);
void
*
ctx
=
zmq_
ctx_new
(
);
assert
(
ctx
);
assert
(
ctx
);
void
*
sb
=
zmq_socket
(
ctx
,
ZMQ_ROUTER
);
void
*
sb
=
zmq_socket
(
ctx
,
ZMQ_ROUTER
);
assert
(
sb
);
assert
(
sb
);
int
rc
=
zmq_bind
(
sb
,
"inproc://a"
);
int
rc
=
zmq_bind
(
sb
,
"inproc://a"
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
void
*
sc
=
zmq_socket
(
ctx
,
ZMQ_DEALER
);
void
*
sc
=
zmq_socket
(
ctx
,
ZMQ_DEALER
);
assert
(
sc
);
assert
(
sc
);
rc
=
zmq_connect
(
sc
,
"inproc://a"
);
rc
=
zmq_connect
(
sc
,
"inproc://a"
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
...
@@ -49,29 +53,31 @@ int main (void)
...
@@ -49,29 +53,31 @@ int main (void)
zmq_msg_t
msg
;
zmq_msg_t
msg
;
rc
=
zmq_msg_init
(
&
msg
);
rc
=
zmq_msg_init
(
&
msg
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_
recvmsg
(
sb
,
&
msg
,
0
);
rc
=
zmq_
msg_recv
(
&
msg
,
sb
,
0
);
assert
(
rc
>=
0
);
assert
(
rc
>=
0
);
int
more
=
zmq_msg_
get
(
&
msg
,
ZMQ_MORE
);
int
more
=
zmq_msg_
more
(
&
msg
);
assert
(
more
==
1
);
assert
(
more
==
1
);
// Then the first part of the message body.
// Then the first part of the message body.
rc
=
zmq_
recvmsg
(
sb
,
&
msg
,
0
);
rc
=
zmq_
msg_recv
(
&
msg
,
sb
,
0
);
assert
(
rc
==
1
);
assert
(
rc
==
1
);
more
=
zmq_msg_
get
(
&
msg
,
ZMQ_MORE
);
more
=
zmq_msg_
more
(
&
msg
);
assert
(
more
==
1
);
assert
(
more
==
1
);
// And finally, the second part of the message body.
// And finally, the second part of the message body.
rc
=
zmq_
recvmsg
(
sb
,
&
msg
,
0
);
rc
=
zmq_
msg_recv
(
&
msg
,
sb
,
0
);
assert
(
rc
==
1
);
assert
(
rc
==
1
);
more
=
zmq_msg_
get
(
&
msg
,
ZMQ_MORE
);
more
=
zmq_msg_
more
(
&
msg
);
assert
(
more
==
0
);
assert
(
more
==
0
);
// Deallocate the infrastructure.
// Deallocate the infrastructure.
rc
=
zmq_close
(
sc
);
rc
=
zmq_close
(
sc
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_close
(
sb
);
rc
=
zmq_close
(
sb
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_term
(
ctx
);
rc
=
zmq_ctx_term
(
ctx
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
return
0
;
return
0
;
}
}
...
...
tests/test_pair_inproc.cpp
View file @
b60689e5
...
@@ -23,9 +23,7 @@
...
@@ -23,9 +23,7 @@
int
main
(
void
)
int
main
(
void
)
{
{
fprintf
(
stderr
,
"test_pair_inproc running...
\n
"
);
void
*
ctx
=
zmq_ctx_new
();
void
*
ctx
=
zmq_init
(
0
);
assert
(
ctx
);
assert
(
ctx
);
void
*
sb
=
zmq_socket
(
ctx
,
ZMQ_PAIR
);
void
*
sb
=
zmq_socket
(
ctx
,
ZMQ_PAIR
);
...
@@ -46,7 +44,7 @@ int main (void)
...
@@ -46,7 +44,7 @@ int main (void)
rc
=
zmq_close
(
sb
);
rc
=
zmq_close
(
sb
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_term
(
ctx
);
rc
=
zmq_
ctx_
term
(
ctx
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
return
0
;
return
0
;
...
...
tests/test_pair_ipc.cpp
View file @
b60689e5
...
@@ -23,9 +23,7 @@
...
@@ -23,9 +23,7 @@
int
main
(
void
)
int
main
(
void
)
{
{
fprintf
(
stderr
,
"test_pair_ipc running...
\n
"
);
void
*
ctx
=
zmq_ctx_new
();
void
*
ctx
=
zmq_init
(
1
);
assert
(
ctx
);
assert
(
ctx
);
void
*
sb
=
zmq_socket
(
ctx
,
ZMQ_PAIR
);
void
*
sb
=
zmq_socket
(
ctx
,
ZMQ_PAIR
);
...
@@ -46,7 +44,7 @@ int main (void)
...
@@ -46,7 +44,7 @@ int main (void)
rc
=
zmq_close
(
sb
);
rc
=
zmq_close
(
sb
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_term
(
ctx
);
rc
=
zmq_
ctx_
term
(
ctx
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
return
0
;
return
0
;
...
...
tests/test_pair_tcp.cpp
View file @
b60689e5
...
@@ -24,9 +24,7 @@
...
@@ -24,9 +24,7 @@
int
main
(
void
)
int
main
(
void
)
{
{
fprintf
(
stderr
,
"test_pair_tcp running...
\n
"
);
void
*
ctx
=
zmq_ctx_new
();
void
*
ctx
=
zmq_init
(
1
);
assert
(
ctx
);
assert
(
ctx
);
void
*
sb
=
zmq_socket
(
ctx
,
ZMQ_PAIR
);
void
*
sb
=
zmq_socket
(
ctx
,
ZMQ_PAIR
);
...
@@ -47,7 +45,7 @@ int main (void)
...
@@ -47,7 +45,7 @@ int main (void)
rc
=
zmq_close
(
sb
);
rc
=
zmq_close
(
sb
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_term
(
ctx
);
rc
=
zmq_
ctx_
term
(
ctx
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
return
0
;
return
0
;
...
...
tests/test_raw_sock.cpp
View file @
b60689e5
/*
/*
Copyright (c) 2007-2012 iMatix Corporation
Copyright (c) 2007-2013 iMatix Corporation
Copyright (c) 2011 250bpm s.r.o.
Copyright (c) 2007-2012 Other contributors as noted in the AUTHORS file
Copyright (c) 2007-2012 Other contributors as noted in the AUTHORS file
This file is part of 0MQ.
This file is part of 0MQ.
...
@@ -19,239 +18,127 @@
...
@@ -19,239 +18,127 @@
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 <sys/types.h>
#include "../include/zmq.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <pthread.h>
#include <netinet/tcp.h>
#include <string.h>
#include <string.h>
#include <std
lib
.h>
#include <std
bool
.h>
#
include <stdio.h>
#
undef NDEBUG
#include <assert.h>
#include <assert.h>
#include <fcntl.h>
#include <zmq.h>
#include <unistd.h>
#include <poll.h>
//ToDo: Windows?
// ZMTP protocol greeting structure
const
char
*
test_str
=
"TEST-STRING"
;
int
tcp_client
()
typedef
unsigned
char
byte
;
{
typedef
struct
{
struct
sockaddr_in
serv_addr
;
byte
signature
[
10
];
// 0xFF 8*0x00 0x7F
struct
hostent
*
server
;
byte
revision
;
// 0x01 = ZMTP/2.0
byte
socktype
;
// Defined in ZMTP spec
const
int
portno
=
5555
;
byte
identity
[
2
];
// Empty message
}
zmtp_greeting_t
;
int
sockfd
=
socket
(
AF_INET
,
SOCK_STREAM
,
0
);
assert
(
sockfd
>=
0
);
server
=
gethostbyname
(
"localhost"
);
assert
(
server
);
memset
(
&
serv_addr
,
0
,
sizeof
serv_addr
);
serv_addr
.
sin_family
=
AF_INET
;
memmove
(
&
serv_addr
.
sin_addr
.
s_addr
,
server
->
h_addr
,
server
->
h_length
);
serv_addr
.
sin_port
=
htons
(
portno
);
int
rc
=
connect
(
sockfd
,
(
struct
sockaddr
*
)
&
serv_addr
,
sizeof
serv_addr
);
assert
(
rc
==
0
);
int
nodelay
=
1
;
rc
=
setsockopt
(
sockfd
,
IPPROTO_TCP
,
TCP_NODELAY
,
(
char
*
)
&
nodelay
,
sizeof
nodelay
);
assert
(
rc
==
0
);
return
sockfd
;
}
int
tcp_server
()
{
int
listenfd
=
socket
(
AF_INET
,
SOCK_STREAM
,
0
);
assert
(
listenfd
!=
-
1
);
int
flag
=
1
;
int
rc
=
setsockopt
(
listenfd
,
SOL_SOCKET
,
SO_REUSEADDR
,
&
flag
,
sizeof
flag
);
assert
(
rc
==
0
);
struct
sockaddr_in
serv_addr
;
memset
(
&
serv_addr
,
0
,
sizeof
serv_addr
);
serv_addr
.
sin_family
=
AF_INET
;
serv_addr
.
sin_addr
.
s_addr
=
htonl
(
INADDR_ANY
);
serv_addr
.
sin_port
=
htons
(
5555
);
rc
=
bind
(
listenfd
,
(
struct
sockaddr
*
)
&
serv_addr
,
sizeof
serv_addr
);
assert
(
rc
==
0
);
rc
=
listen
(
listenfd
,
8
);
#define ZMTP_DEALER 5 // Socket type constants
assert
(
rc
==
0
);
#define ZMTP_ROUTER 6
int
sockfd
=
accept
(
listenfd
,
NULL
,
NULL
);
assert
(
sockfd
!=
-
1
);
rc
=
close
(
listenfd
);
assert
(
rc
==
0
);
int
flags
=
fcntl
(
sockfd
,
F_GETFL
,
0
);
if
(
flags
==
-
1
)
flags
=
0
;
rc
=
fcntl
(
sockfd
,
F_SETFL
,
flags
|
O_NONBLOCK
);
assert
(
rc
!=
-
1
);
return
sockfd
;
}
void
tcp_client_write
(
int
sockfd
,
const
void
*
buf
,
int
buf_len
)
{
assert
(
buf
);
int
n
=
write
(
sockfd
,
buf
,
buf_len
);
assert
(
n
>=
0
);
}
void
tcp_client_read
(
int
sockfd
)
{
struct
timeval
tm
;
tm
.
tv_sec
=
1
;
tm
.
tv_usec
=
0
;
fd_set
r
;
char
buffer
[
16
];
// This is a greeting matching what 0MQ will send us; note the
// 8-byte size is set to 1 for backwards compatibility
FD_ZERO
(
&
r
);
static
zmtp_greeting_t
greeting
FD_SET
(
sockfd
,
&
r
)
;
=
{
{
0xFF
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
1
,
0x7F
},
1
,
0
,
{
0
,
0
}
}
;
int
sr
=
select
(
sockfd
+
1
,
&
r
,
NULL
,
NULL
,
&
tm
);
int
main
(
void
)
assert
(
sr
>
0
);
int
n
=
read
(
sockfd
,
buffer
,
16
);
assert
(
n
>
0
);
assert
(
memcmp
(
buffer
,
test_str
,
strlen
(
test_str
))
==
0
);
}
size_t
tcp_read
(
int
s
,
char
*
buf
,
size_t
bufsize
)
{
{
size_t
bytes_read
=
0
;
int
rc
;
struct
pollfd
pfd
=
{
s
,
POLLIN
};
int
rc
=
poll
(
&
pfd
,
1
,
100
);
while
(
rc
>
0
&&
bytes_read
<
bufsize
)
{
// Set up our context and sockets
int
n
=
read
(
s
,
buf
+
bytes_read
,
bufsize
-
bytes_read
);
void
*
ctx
=
zmq_ctx_new
();
if
(
n
<=
0
)
return
bytes_read
;
bytes_read
+=
n
;
rc
=
poll
(
&
pfd
,
1
,
100
);
}
return
bytes_read
;
}
void
tcp_client_close
(
int
sockfd
)
{
close
(
sockfd
);
}
void
test_zmq_connect
()
{
void
*
ctx
=
zmq_init
(
1
);
assert
(
ctx
);
assert
(
ctx
);
void
*
zs
=
zmq_socket
(
ctx
,
ZMQ_ROUTER
);
// We'll be using this socket in raw mode
assert
(
zs
);
void
*
router
=
zmq_socket
(
ctx
,
ZMQ_ROUTER
);
assert
(
router
);
int
rc
=
zmq_setsockopt
(
zs
,
ZMQ_IDENTITY
,
"X"
,
1
);
int
on
=
1
;
rc
=
zmq_setsockopt
(
router
,
ZMQ_ROUTER_RAW
,
&
on
,
sizeof
(
on
));
assert
(
rc
==
0
);
assert
(
rc
==
0
);
int
zero
=
0
;
int
raw_sock
=
1
;
rc
=
zmq_setsockopt
(
router
,
ZMQ_LINGER
,
&
zero
,
sizeof
(
zero
));
rc
=
zmq_setsockopt
(
zs
,
ZMQ_ROUTER_RAW
,
&
raw_sock
,
sizeof
raw_sock
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_bind
(
router
,
"tcp://*:5555"
);
rc
=
zmq_connect
(
zs
,
"tcp://127.0.0.1:5555"
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
int
i
;
// We'll be using this socket as the other peer
for
(
i
=
0
;
i
<
8
;
i
++
)
{
void
*
dealer
=
zmq_socket
(
ctx
,
ZMQ_DEALER
);
int
server_fd
=
tcp_server
();
assert
(
dealer
);
assert
(
server_fd
!=
-
1
);
rc
=
zmq_setsockopt
(
dealer
,
ZMQ_LINGER
,
&
zero
,
sizeof
(
zero
));
zmq_msg_t
msg
;
rc
=
zmq_msg_init_size
(
&
msg
,
strlen
(
test_str
));
assert
(
rc
==
0
);
memcpy
(
zmq_msg_data
(
&
msg
),
test_str
,
strlen
(
test_str
));
rc
=
zmq_msg_send
(
&
msg
,
zs
,
0
);
char
buffer
[
128
];
size_t
bytes_read
=
tcp_read
(
server_fd
,
buffer
,
sizeof
buffer
);
assert
(
bytes_read
==
strlen
(
test_str
)
&&
memcmp
(
buffer
,
test_str
,
bytes_read
)
==
0
);
rc
=
close
(
server_fd
);
assert
(
rc
==
0
);
}
rc
=
zmq_close
(
zs
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_connect
(
dealer
,
"tcp://localhost:5555"
);
rc
=
zmq_term
(
ctx
);
// Send a message on the dealer socket
assert
(
rc
==
0
);
rc
=
zmq_send
(
dealer
,
"Hello"
,
5
,
0
);
}
assert
(
rc
==
5
);
int
main
()
// First frame is identity
{
zmq_msg_t
identity
;
fprintf
(
stderr
,
"test_raw_sock running...
\n
"
);
rc
=
zmq_msg_init
(
&
identity
);
zmq_msg_t
message
;
zmq_msg_t
id
;
//===================
void
*
ctx
=
zmq_init
(
1
);
assert
(
ctx
);
void
*
sb
=
zmq_socket
(
ctx
,
ZMQ_ROUTER
);
assert
(
sb
);
int
raw_sock
=
1
;
int
rc
=
zmq_setsockopt
(
sb
,
ZMQ_ROUTER_RAW
,
&
raw_sock
,
sizeof
raw_sock
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_bind
(
sb
,
"tcp://127.0.0.1:5555"
);
rc
=
zmq_msg_recv
(
&
identity
,
router
,
0
);
assert
(
rc
>
0
);
assert
(
zmq_msg_more
(
&
identity
));
// Second frame is greeting signature
byte
buffer
[
255
];
rc
=
zmq_recv
(
router
,
buffer
,
255
,
0
);
assert
(
rc
==
10
);
assert
(
memcmp
(
buffer
,
greeting
.
signature
,
10
)
==
0
);
// Send our own protocol greeting
rc
=
zmq_msg_send
(
&
identity
,
router
,
ZMQ_SNDMORE
);
assert
(
rc
>
0
);
greeting
.
socktype
=
ZMTP_ROUTER
;
rc
=
zmq_send
(
router
,
&
greeting
,
sizeof
(
greeting
),
0
);
assert
(
rc
==
sizeof
(
greeting
));
// Now we expect the data from the DEALER socket
// First frame is, again, the identity of the connection
rc
=
zmq_msg_recv
(
&
identity
,
router
,
0
);
assert
(
rc
>
0
);
assert
(
zmq_msg_more
(
&
identity
));
// Second frame contains all remaining data from DEALER
rc
=
zmq_recv
(
router
,
buffer
,
255
,
0
);
assert
(
rc
==
11
);
// First four bytes are [revision][socktype][identity]
assert
(
buffer
[
0
]
==
1
);
// Revision = 1
assert
(
buffer
[
1
]
==
ZMTP_DEALER
);
// Identity is 2 byte message
assert
(
buffer
[
2
]
==
0
);
// Flags = 0
assert
(
buffer
[
3
]
==
0
);
// Size = 0
// Then we have a 5-byte message "Hello"
assert
(
buffer
[
4
]
==
0
);
// Flags = 0
assert
(
buffer
[
5
]
==
5
);
// Size = 5
assert
(
memcmp
(
buffer
+
6
,
"Hello"
,
5
)
==
0
);
// Send "World" back to DEALER
rc
=
zmq_msg_send
(
&
identity
,
router
,
ZMQ_SNDMORE
);
assert
(
rc
>
0
);
byte
world
[]
=
{
0
,
5
,
'W'
,
'o'
,
'r'
,
'l'
,
'd'
};
rc
=
zmq_send
(
router
,
world
,
sizeof
(
world
),
0
);
assert
(
rc
==
sizeof
(
world
));
// Expect response on DEALER socket
rc
=
zmq_recv
(
dealer
,
buffer
,
255
,
0
);
assert
(
rc
==
5
);
assert
(
memcmp
(
buffer
,
"World"
,
5
)
==
0
);
rc
=
zmq_close
(
dealer
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
int
sock_fd
=
tcp_client
();
rc
=
zmq_close
(
router
);
assert
(
sock_fd
>=
0
);
// ===================
zmq_msg_init
(
&
message
);
zmq_msg_init
(
&
id
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
zmq_pollitem_t
items
[]
=
{
rc
=
zmq_ctx_term
(
ctx
);
{
sb
,
0
,
ZMQ_POLLIN
,
0
},
assert
(
rc
==
0
);
};
tcp_client_write
(
sock_fd
,
test_str
,
strlen
(
test_str
));
zmq_poll
(
items
,
1
,
500
);
assert
(
items
[
0
].
revents
&
ZMQ_POLLIN
);
int
n
=
zmq_msg_recv
(
&
id
,
sb
,
0
);
assert
(
n
>
0
);
n
=
zmq_msg_recv
(
&
message
,
sb
,
0
);
assert
(
n
>
0
);
assert
(
memcmp
(
zmq_msg_data
(
&
message
),
test_str
,
strlen
(
test_str
))
==
0
);
zmq_msg_send
(
&
id
,
sb
,
ZMQ_SNDMORE
);
zmq_msg_send
(
&
message
,
sb
,
ZMQ_SNDMORE
);
// SNDMORE option is ignored
tcp_client_read
(
sock_fd
);
tcp_client_close
(
sock_fd
);
zmq_msg_close
(
&
id
);
zmq_msg_close
(
&
message
);
zmq_close
(
sb
);
zmq_term
(
ctx
);
test_zmq_connect
();
fprintf
(
stderr
,
"test_raw_sock PASSED.
\n
"
);
return
0
;
return
0
;
}
}
tests/test_reqrep_device.cpp
View file @
b60689e5
...
@@ -28,9 +28,7 @@
...
@@ -28,9 +28,7 @@
int
main
(
void
)
int
main
(
void
)
{
{
fprintf
(
stderr
,
"test_reqrep_device running...
\n
"
);
void
*
ctx
=
zmq_ctx_new
();
void
*
ctx
=
zmq_init
(
1
);
assert
(
ctx
);
assert
(
ctx
);
// Create a req/rep device.
// Create a req/rep device.
...
@@ -66,13 +64,13 @@ int main (void)
...
@@ -66,13 +64,13 @@ int main (void)
zmq_msg_t
msg
;
zmq_msg_t
msg
;
rc
=
zmq_msg_init
(
&
msg
);
rc
=
zmq_msg_init
(
&
msg
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_
recvmsg
(
router
,
&
msg
,
0
);
rc
=
zmq_
msg_recv
(
&
msg
,
router
,
0
);
assert
(
rc
>=
0
);
assert
(
rc
>=
0
);
int
rcvmore
;
int
rcvmore
;
size_t
sz
=
sizeof
(
rcvmore
);
size_t
sz
=
sizeof
(
rcvmore
);
rc
=
zmq_getsockopt
(
router
,
ZMQ_RCVMORE
,
&
rcvmore
,
&
sz
);
rc
=
zmq_getsockopt
(
router
,
ZMQ_RCVMORE
,
&
rcvmore
,
&
sz
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_
sendmsg
(
dealer
,
&
msg
,
rcvmore
?
ZMQ_SNDMORE
:
0
);
rc
=
zmq_
msg_send
(
&
msg
,
dealer
,
rcvmore
?
ZMQ_SNDMORE
:
0
);
assert
(
rc
>=
0
);
assert
(
rc
>=
0
);
}
}
...
@@ -104,12 +102,12 @@ int main (void)
...
@@ -104,12 +102,12 @@ int main (void)
zmq_msg_t
msg
;
zmq_msg_t
msg
;
rc
=
zmq_msg_init
(
&
msg
);
rc
=
zmq_msg_init
(
&
msg
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_
recvmsg
(
dealer
,
&
msg
,
0
);
rc
=
zmq_
msg_recv
(
&
msg
,
dealer
,
0
);
assert
(
rc
>=
0
);
assert
(
rc
>=
0
);
int
rcvmore
;
int
rcvmore
;
rc
=
zmq_getsockopt
(
dealer
,
ZMQ_RCVMORE
,
&
rcvmore
,
&
sz
);
rc
=
zmq_getsockopt
(
dealer
,
ZMQ_RCVMORE
,
&
rcvmore
,
&
sz
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_
sendmsg
(
router
,
&
msg
,
rcvmore
?
ZMQ_SNDMORE
:
0
);
rc
=
zmq_
msg_send
(
&
msg
,
router
,
rcvmore
?
ZMQ_SNDMORE
:
0
);
assert
(
rc
>=
0
);
assert
(
rc
>=
0
);
}
}
...
@@ -136,7 +134,7 @@ int main (void)
...
@@ -136,7 +134,7 @@ int main (void)
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_close
(
dealer
);
rc
=
zmq_close
(
dealer
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_term
(
ctx
);
rc
=
zmq_
ctx_
term
(
ctx
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
return
0
;
return
0
;
...
...
tests/test_reqrep_inproc.cpp
View file @
b60689e5
...
@@ -23,9 +23,7 @@
...
@@ -23,9 +23,7 @@
int
main
(
void
)
int
main
(
void
)
{
{
fprintf
(
stderr
,
"test_reqrep_inproc running...
\n
"
);
void
*
ctx
=
zmq_ctx_new
();
void
*
ctx
=
zmq_init
(
0
);
assert
(
ctx
);
assert
(
ctx
);
void
*
sb
=
zmq_socket
(
ctx
,
ZMQ_REP
);
void
*
sb
=
zmq_socket
(
ctx
,
ZMQ_REP
);
...
@@ -46,7 +44,7 @@ int main (void)
...
@@ -46,7 +44,7 @@ int main (void)
rc
=
zmq_close
(
sb
);
rc
=
zmq_close
(
sb
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_term
(
ctx
);
rc
=
zmq_
ctx_
term
(
ctx
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
return
0
;
return
0
;
...
...
tests/test_reqrep_ipc.cpp
View file @
b60689e5
...
@@ -23,9 +23,7 @@
...
@@ -23,9 +23,7 @@
int
main
(
void
)
int
main
(
void
)
{
{
fprintf
(
stderr
,
"test_reqrep_ipc running...
\n
"
);
void
*
ctx
=
zmq_ctx_new
();
void
*
ctx
=
zmq_init
(
1
);
assert
(
ctx
);
assert
(
ctx
);
void
*
sb
=
zmq_socket
(
ctx
,
ZMQ_REP
);
void
*
sb
=
zmq_socket
(
ctx
,
ZMQ_REP
);
...
@@ -46,7 +44,7 @@ int main (void)
...
@@ -46,7 +44,7 @@ int main (void)
rc
=
zmq_close
(
sb
);
rc
=
zmq_close
(
sb
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_term
(
ctx
);
rc
=
zmq_
ctx_
term
(
ctx
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
return
0
;
return
0
;
...
...
tests/test_reqrep_tcp.cpp
View file @
b60689e5
...
@@ -24,9 +24,7 @@
...
@@ -24,9 +24,7 @@
int
main
(
void
)
int
main
(
void
)
{
{
fprintf
(
stderr
,
"test_reqrep_tcp running...
\n
"
);
void
*
ctx
=
zmq_ctx_new
();
void
*
ctx
=
zmq_init
(
1
);
assert
(
ctx
);
assert
(
ctx
);
void
*
sb
=
zmq_socket
(
ctx
,
ZMQ_REP
);
void
*
sb
=
zmq_socket
(
ctx
,
ZMQ_REP
);
...
@@ -47,7 +45,7 @@ int main (void)
...
@@ -47,7 +45,7 @@ int main (void)
rc
=
zmq_close
(
sb
);
rc
=
zmq_close
(
sb
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_term
(
ctx
);
rc
=
zmq_
ctx_
term
(
ctx
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
return
0
;
return
0
;
...
...
tests/test_router_mandatory.cpp
View file @
b60689e5
/*
/*
Copyright (c) 2010-2011 250bpm s.r.o.
Copyright (c) 2007-2013 iMatix Corporation
Copyright (c) 2011 iMatix Corporation
Copyright (c) 2010-2011 Other contributors as noted in the AUTHORS file
Copyright (c) 2010-2011 Other contributors as noted in the AUTHORS file
This file is part of 0MQ.
This file is part of 0MQ.
...
@@ -19,86 +18,67 @@
...
@@ -19,86 +18,67 @@
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 "../include/zmq.h"
#include <stdio.h>
#include <stdio.h>
#include "testutil.hpp"
#include <string.h>
#include "../include/zmq_utils.h"
#undef NDEBUG
#include <assert.h>
int
main
(
void
)
int
main
(
void
)
{
{
fprintf
(
stderr
,
"test_router_mandatory running...
\n
"
);
void
*
ctx
=
zmq_ctx_new
();
void
*
ctx
=
zmq_init
(
1
);
assert
(
ctx
);
assert
(
ctx
);
void
*
router
=
zmq_socket
(
ctx
,
ZMQ_ROUTER
);
assert
(
router
);
// Creating the first socket.
int
rc
=
zmq_bind
(
router
,
"tcp://127.0.0.1:5560"
);
void
*
sa
=
zmq_socket
(
ctx
,
ZMQ_ROUTER
);
assert
(
sa
);
int
hwm
=
1
;
int
rc
=
zmq_setsockopt
(
sa
,
ZMQ_SNDHWM
,
&
hwm
,
sizeof
(
hwm
));
assert
(
rc
==
0
);
rc
=
zmq_bind
(
sa
,
"tcp://127.0.0.1:15560"
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
// Sending a message to an unknown peer with the default setting
// Send a message to an unknown peer with the default setting
rc
=
zmq_send
(
sa
,
"UNKNOWN"
,
7
,
ZMQ_SNDMORE
);
// This will not report any error
rc
=
zmq_send
(
router
,
"UNKNOWN"
,
7
,
ZMQ_SNDMORE
);
assert
(
rc
==
7
);
assert
(
rc
==
7
);
rc
=
zmq_send
(
sa
,
"DATA"
,
4
,
0
);
rc
=
zmq_send
(
router
,
"DATA"
,
4
,
0
);
assert
(
rc
==
4
);
assert
(
rc
==
4
);
// Send a message to an unknown peer with mandatory routing
// This will fail
int
mandatory
=
1
;
int
mandatory
=
1
;
rc
=
zmq_setsockopt
(
router
,
ZMQ_ROUTER_MANDATORY
,
&
mandatory
,
sizeof
(
mandatory
));
// Set mandatory routing on socket
rc
=
zmq_setsockopt
(
sa
,
ZMQ_ROUTER_MANDATORY
,
&
mandatory
,
sizeof
(
mandatory
));
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_send
(
router
,
"UNKNOWN"
,
7
,
ZMQ_SNDMORE
);
// Send a message and check that it fails
rc
=
zmq_send
(
sa
,
"UNKNOWN"
,
7
,
ZMQ_SNDMORE
|
ZMQ_DONTWAIT
);
assert
(
rc
==
-
1
&&
errno
==
EHOSTUNREACH
);
assert
(
rc
==
-
1
&&
errno
==
EHOSTUNREACH
);
// Create a valid socket
// Create dealer called "X" and connect it to our router
void
*
sb
=
zmq_socket
(
ctx
,
ZMQ_DEALER
);
void
*
dealer
=
zmq_socket
(
ctx
,
ZMQ_DEALER
);
assert
(
sb
);
assert
(
dealer
);
rc
=
zmq_setsockopt
(
dealer
,
ZMQ_IDENTITY
,
"X"
,
1
);
rc
=
zmq_setsockopt
(
sb
,
ZMQ_RCVHWM
,
&
hwm
,
sizeof
(
hwm
));
assert
(
rc
==
0
);
rc
=
zmq_setsockopt
(
sb
,
ZMQ_IDENTITY
,
"X"
,
1
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_connect
(
dealer
,
"tcp://127.0.0.1:5560"
);
rc
=
zmq_connect
(
sb
,
"tcp://127.0.0.1:15560"
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
// wait until connect
// Get message from dealer to know when connection is ready
zmq_sleep
(
1
);
char
buffer
[
255
];
rc
=
zmq_send
(
dealer
,
"Hello"
,
5
,
0
);
assert
(
rc
==
5
);
rc
=
zmq_recv
(
router
,
buffer
,
255
,
0
);
assert
(
rc
==
1
);
assert
(
buffer
[
0
]
==
'X'
);
// make it full and check that it fails
// Send a message to connected dealer now
rc
=
zmq_send
(
sa
,
"X"
,
1
,
ZMQ_SNDMORE
);
// It should work
rc
=
zmq_send
(
router
,
"X"
,
1
,
ZMQ_SNDMORE
);
assert
(
rc
==
1
);
assert
(
rc
==
1
);
rc
=
zmq_send
(
sa
,
"DATA1
"
,
5
,
0
);
rc
=
zmq_send
(
router
,
"Hello
"
,
5
,
0
);
assert
(
rc
==
5
);
assert
(
rc
==
5
);
rc
=
zmq_send
(
sa
,
"X"
,
1
,
ZMQ_SNDMORE
|
ZMQ_DONTWAIT
);
if
(
rc
==
1
)
{
// the first frame has been sent
rc
=
zmq_send
(
sa
,
"DATA2"
,
5
,
0
);
assert
(
rc
==
5
);
// send more
rc
=
zmq_close
(
router
);
rc
=
zmq_send
(
sa
,
"X"
,
1
,
ZMQ_SNDMORE
|
ZMQ_DONTWAIT
);
}
assert
(
rc
==
-
1
&&
errno
==
EAGAIN
);
rc
=
zmq_close
(
sa
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_close
(
sb
);
rc
=
zmq_close
(
dealer
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_term
(
ctx
);
rc
=
zmq_
ctx_
term
(
ctx
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
return
0
;
return
0
;
...
...
tests/test_shutdown_stress.cpp
View file @
b60689e5
...
@@ -48,7 +48,6 @@ extern "C"
...
@@ -48,7 +48,6 @@ extern "C"
int
main
(
void
)
int
main
(
void
)
{
{
void
*
ctx
;
void
*
s1
;
void
*
s1
;
void
*
s2
;
void
*
s2
;
int
i
;
int
i
;
...
@@ -56,13 +55,12 @@ int main (void)
...
@@ -56,13 +55,12 @@ int main (void)
int
rc
;
int
rc
;
pthread_t
threads
[
THREAD_COUNT
];
pthread_t
threads
[
THREAD_COUNT
];
fprintf
(
stderr
,
"test_shutdown_stress running...
\n
"
);
for
(
j
=
0
;
j
!=
10
;
j
++
)
{
for
(
j
=
0
;
j
!=
10
;
j
++
)
{
// Check the shutdown with many parallel I/O threads.
// Check the shutdown with many parallel I/O threads.
ctx
=
zmq_init
(
7
);
void
*
ctx
=
zmq_ctx_new
(
);
assert
(
ctx
);
assert
(
ctx
);
zmq_ctx_set
(
ctx
,
ZMQ_IO_THREADS
,
7
);
s1
=
zmq_socket
(
ctx
,
ZMQ_PUB
);
s1
=
zmq_socket
(
ctx
,
ZMQ_PUB
);
assert
(
s1
);
assert
(
s1
);
...
@@ -85,7 +83,7 @@ int main (void)
...
@@ -85,7 +83,7 @@ int main (void)
rc
=
zmq_close
(
s1
);
rc
=
zmq_close
(
s1
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_term
(
ctx
);
rc
=
zmq_
ctx_
term
(
ctx
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
}
}
...
...
tests/test_sub_forward.cpp
View file @
b60689e5
...
@@ -20,20 +20,17 @@
...
@@ -20,20 +20,17 @@
*/
*/
#include "../include/zmq.h"
#include "../include/zmq.h"
#include "../include/zmq_utils.h"
#include <stdio.h>
#include <stdio.h>
#include <time.h>
#undef NDEBUG
#undef NDEBUG
#include <assert.h>
#include <assert.h>
int
main
(
void
)
int
main
(
void
)
{
{
fprintf
(
stderr
,
"test_sub_forward running...
\n
"
);
void
*
ctx
=
zmq_ctx_new
();
void
*
ctx
=
zmq_init
(
1
);
assert
(
ctx
);
assert
(
ctx
);
// First, create an intermediate device
.
// First, create an intermediate device
void
*
xpub
=
zmq_socket
(
ctx
,
ZMQ_XPUB
);
void
*
xpub
=
zmq_socket
(
ctx
,
ZMQ_XPUB
);
assert
(
xpub
);
assert
(
xpub
);
int
rc
=
zmq_bind
(
xpub
,
"tcp://127.0.0.1:5560"
);
int
rc
=
zmq_bind
(
xpub
,
"tcp://127.0.0.1:5560"
);
...
@@ -43,13 +40,13 @@ int main (void)
...
@@ -43,13 +40,13 @@ int main (void)
rc
=
zmq_bind
(
xsub
,
"tcp://127.0.0.1:5561"
);
rc
=
zmq_bind
(
xsub
,
"tcp://127.0.0.1:5561"
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
// Create a publisher
.
// Create a publisher
void
*
pub
=
zmq_socket
(
ctx
,
ZMQ_PUB
);
void
*
pub
=
zmq_socket
(
ctx
,
ZMQ_PUB
);
assert
(
pub
);
assert
(
pub
);
rc
=
zmq_connect
(
pub
,
"tcp://127.0.0.1:5561"
);
rc
=
zmq_connect
(
pub
,
"tcp://127.0.0.1:5561"
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
// Create a subscriber
.
// Create a subscriber
void
*
sub
=
zmq_socket
(
ctx
,
ZMQ_SUB
);
void
*
sub
=
zmq_socket
(
ctx
,
ZMQ_SUB
);
assert
(
sub
);
assert
(
sub
);
rc
=
zmq_connect
(
sub
,
"tcp://127.0.0.1:5560"
);
rc
=
zmq_connect
(
sub
,
"tcp://127.0.0.1:5560"
);
...
@@ -59,27 +56,28 @@ int main (void)
...
@@ -59,27 +56,28 @@ int main (void)
rc
=
zmq_setsockopt
(
sub
,
ZMQ_SUBSCRIBE
,
""
,
0
);
rc
=
zmq_setsockopt
(
sub
,
ZMQ_SUBSCRIBE
,
""
,
0
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
// Pass the subscription upstream through the device
.
// Pass the subscription upstream through the device
char
buff
[
32
];
char
buff
[
32
];
rc
=
zmq_recv
(
xpub
,
buff
,
sizeof
(
buff
),
0
);
rc
=
zmq_recv
(
xpub
,
buff
,
sizeof
(
buff
),
0
);
assert
(
rc
>=
0
);
assert
(
rc
>=
0
);
rc
=
zmq_send
(
xsub
,
buff
,
rc
,
0
);
rc
=
zmq_send
(
xsub
,
buff
,
rc
,
0
);
assert
(
rc
>=
0
);
assert
(
rc
>=
0
);
// Wait a bit till the subscription gets to the publisher.
// Wait a bit till the subscription gets to the publisher
zmq_sleep
(
1
);
struct
timespec
t
=
{
0
,
250
*
1000000
};
nanosleep
(
&
t
,
NULL
);
// Send an empty message
.
// Send an empty message
rc
=
zmq_send
(
pub
,
NULL
,
0
,
0
);
rc
=
zmq_send
(
pub
,
NULL
,
0
,
0
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
// Pass the message downstream through the device
.
// Pass the message downstream through the device
rc
=
zmq_recv
(
xsub
,
buff
,
sizeof
(
buff
),
0
);
rc
=
zmq_recv
(
xsub
,
buff
,
sizeof
(
buff
),
0
);
assert
(
rc
>=
0
);
assert
(
rc
>=
0
);
rc
=
zmq_send
(
xpub
,
buff
,
rc
,
0
);
rc
=
zmq_send
(
xpub
,
buff
,
rc
,
0
);
assert
(
rc
>=
0
);
assert
(
rc
>=
0
);
// Receive the message in the subscriber
.
// Receive the message in the subscriber
rc
=
zmq_recv
(
sub
,
buff
,
sizeof
(
buff
),
0
);
rc
=
zmq_recv
(
sub
,
buff
,
sizeof
(
buff
),
0
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
...
@@ -92,7 +90,7 @@ int main (void)
...
@@ -92,7 +90,7 @@ int main (void)
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_close
(
sub
);
rc
=
zmq_close
(
sub
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_term
(
ctx
);
rc
=
zmq_
ctx_
term
(
ctx
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
return
0
;
return
0
;
...
...
tests/test_term_endpoint.cpp
View file @
b60689e5
...
@@ -20,9 +20,9 @@
...
@@ -20,9 +20,9 @@
*/
*/
#include "../include/zmq.h"
#include "../include/zmq.h"
#include "../include/zmq_utils.h"
#include <string.h>
#include <string.h>
#include <unistd.h>
#include <unistd.h>
#include <time.h>
#undef NDEBUG
#undef NDEBUG
#include <assert.h>
#include <assert.h>
...
@@ -33,10 +33,8 @@ int main (void)
...
@@ -33,10 +33,8 @@ int main (void)
char
buf
[
32
];
char
buf
[
32
];
const
char
*
ep
=
"tcp://127.0.0.1:5560"
;
const
char
*
ep
=
"tcp://127.0.0.1:5560"
;
fprintf
(
stderr
,
"unbind endpoint test running...
\n
"
);
// Create infrastructure.
// Create infrastructure.
void
*
ctx
=
zmq_
init
(
1
);
void
*
ctx
=
zmq_
ctx_new
(
);
assert
(
ctx
);
assert
(
ctx
);
void
*
push
=
zmq_socket
(
ctx
,
ZMQ_PUSH
);
void
*
push
=
zmq_socket
(
ctx
,
ZMQ_PUSH
);
assert
(
push
);
assert
(
push
);
...
@@ -47,38 +45,34 @@ int main (void)
...
@@ -47,38 +45,34 @@ int main (void)
rc
=
zmq_connect
(
pull
,
ep
);
rc
=
zmq_connect
(
pull
,
ep
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
// Pass one message through to ensure the connection is established
.
// Pass one message through to ensure the connection is established
rc
=
zmq_send
(
push
,
"ABC"
,
3
,
0
);
rc
=
zmq_send
(
push
,
"ABC"
,
3
,
0
);
assert
(
rc
==
3
);
assert
(
rc
==
3
);
rc
=
zmq_recv
(
pull
,
buf
,
sizeof
(
buf
),
0
);
rc
=
zmq_recv
(
pull
,
buf
,
sizeof
(
buf
),
0
);
assert
(
rc
==
3
);
assert
(
rc
==
3
);
//
Unbind the lisn
ening endpoint
//
Unbind the list
ening endpoint
rc
=
zmq_unbind
(
push
,
ep
);
rc
=
zmq_unbind
(
push
,
ep
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
// Let events some time
// Allow unbind to settle
zmq_sleep
(
1
);
struct
timespec
t
=
{
0
,
250
*
1000000
};
nanosleep
(
&
t
,
NULL
);
// Check that sending would block (there's no outbound connection)
.
// Check that sending would block (there's no outbound connection)
rc
=
zmq_send
(
push
,
"ABC"
,
3
,
ZMQ_DONTWAIT
);
rc
=
zmq_send
(
push
,
"ABC"
,
3
,
ZMQ_DONTWAIT
);
assert
(
rc
==
-
1
&&
zmq_errno
()
==
EAGAIN
);
assert
(
rc
==
-
1
&&
zmq_errno
()
==
EAGAIN
);
// Clean up
.
// Clean up
rc
=
zmq_close
(
pull
);
rc
=
zmq_close
(
pull
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_close
(
push
);
rc
=
zmq_close
(
push
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_term
(
ctx
);
rc
=
zmq_
ctx_
term
(
ctx
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
// Create infrastructure
// Now the other way round.
ctx
=
zmq_ctx_new
();
fprintf
(
stderr
,
"disconnect endpoint test running...
\n
"
);
// Create infrastructure.
ctx
=
zmq_init
(
1
);
assert
(
ctx
);
assert
(
ctx
);
push
=
zmq_socket
(
ctx
,
ZMQ_PUSH
);
push
=
zmq_socket
(
ctx
,
ZMQ_PUSH
);
assert
(
push
);
assert
(
push
);
...
@@ -95,12 +89,12 @@ int main (void)
...
@@ -95,12 +89,12 @@ int main (void)
rc
=
zmq_recv
(
pull
,
buf
,
sizeof
(
buf
),
0
);
rc
=
zmq_recv
(
pull
,
buf
,
sizeof
(
buf
),
0
);
assert
(
rc
==
3
);
assert
(
rc
==
3
);
// Disconnect the bound endpoint
//
Disconnect the bound endpoint
rc
=
zmq_disconnect
(
push
,
ep
);
rc
=
zmq_disconnect
(
push
,
ep
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
//
Let events some tim
e
//
Allow disconnect to settl
e
zmq_sleep
(
1
);
nanosleep
(
&
t
,
NULL
);
// Check that sending would block (there's no inbound connections).
// Check that sending would block (there's no inbound connections).
rc
=
zmq_send
(
push
,
"ABC"
,
3
,
ZMQ_DONTWAIT
);
rc
=
zmq_send
(
push
,
"ABC"
,
3
,
ZMQ_DONTWAIT
);
...
@@ -111,7 +105,7 @@ int main (void)
...
@@ -111,7 +105,7 @@ int main (void)
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_close
(
push
);
rc
=
zmq_close
(
push
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_term
(
ctx
);
rc
=
zmq_
ctx_
term
(
ctx
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
return
0
;
return
0
;
...
...
tests/test_timeo.cpp
View file @
b60689e5
/*
/*
Copyright (c) 2007-2013 iMatix Corporation
Copyright (c) 2010-2011 250bpm s.r.o.
Copyright (c) 2010-2011 250bpm s.r.o.
Copyright (c) 2010-2011 Other contributors as noted in the AUTHORS file
Copyright (c) 2010-2011 Other contributors as noted in the AUTHORS file
...
@@ -19,101 +20,69 @@
...
@@ -19,101 +20,69 @@
*/
*/
#include "../include/zmq.h"
#include "../include/zmq.h"
#include "../include/zmq_utils.h"
#include <sys/time.h>
#include <pthread.h>
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <string.h>
#undef NDEBUG
#undef NDEBUG
#include <assert.h>
#include <assert.h>
extern
"C"
{
void
*
worker
(
void
*
ctx
)
{
// Worker thread connects after delay of 1 second. Then it waits
// for 1 more second, so that async connect has time to succeed.
zmq_sleep
(
1
);
void
*
sc
=
zmq_socket
(
ctx
,
ZMQ_PUSH
);
assert
(
sc
);
int
rc
=
zmq_connect
(
sc
,
"inproc://timeout_test"
);
assert
(
rc
==
0
);
zmq_sleep
(
1
);
rc
=
zmq_close
(
sc
);
assert
(
rc
==
0
);
return
NULL
;
}
}
int
main
(
void
)
int
main
(
void
)
{
{
fprintf
(
stderr
,
"test_timeo running...
\n
"
);
void
*
ctx
=
zmq_ctx_new
();
void
*
ctx
=
zmq_init
(
1
);
assert
(
ctx
);
assert
(
ctx
);
// Create a disconnected socket.
void
*
frontend
=
zmq_socket
(
ctx
,
ZMQ_DEALER
);
void
*
sb
=
zmq_socket
(
ctx
,
ZMQ_PULL
);
assert
(
frontend
);
assert
(
sb
);
int
rc
=
zmq_bind
(
frontend
,
"inproc://timeout_test"
);
int
rc
=
zmq_bind
(
sb
,
"inproc://timeout_test"
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
//
Check whether non-blocking recv returns immediately.
//
Receive on disconnected socket returns immediately
char
buf
[]
=
"12345678ABCDEFGH12345678abcdefgh"
;
char
buf
fer
[
32
]
;
rc
=
zmq_recv
(
sb
,
buf
,
32
,
ZMQ_DONTWAIT
);
rc
=
zmq_recv
(
frontend
,
buffer
,
32
,
ZMQ_DONTWAIT
);
assert
(
rc
==
-
1
);
assert
(
rc
==
-
1
);
assert
(
zmq_errno
()
==
EAGAIN
);
assert
(
zmq_errno
()
==
EAGAIN
);
// Check whether receive timeout is honored
int
timeout
=
250
;
rc
=
zmq_setsockopt
(
frontend
,
ZMQ_RCVTIMEO
,
&
timeout
,
sizeof
(
int
));
assert
(
rc
==
0
);
// Check whether recv timeout is honoured.
struct
timeval
before
,
after
;
int
timeout
=
500
;
gettimeofday
(
&
before
,
NULL
);
size_t
timeout_size
=
sizeof
timeout
;
rc
=
zmq_recv
(
frontend
,
buffer
,
32
,
0
);
rc
=
zmq_setsockopt
(
sb
,
ZMQ_RCVTIMEO
,
&
timeout
,
timeout_size
);
assert
(
rc
==
0
);
void
*
watch
=
zmq_stopwatch_start
();
rc
=
zmq_recv
(
sb
,
buf
,
32
,
0
);
assert
(
rc
==
-
1
);
assert
(
rc
==
-
1
);
assert
(
zmq_errno
()
==
EAGAIN
);
assert
(
zmq_errno
()
==
EAGAIN
);
unsigned
long
elapsed
=
zmq_stopwatch_stop
(
watch
);
gettimeofday
(
&
after
,
NULL
);
assert
(
elapsed
>
440000
&&
elapsed
<
550000
);
long
elapsed
=
(
long
)
// Check whether connection during the wait doesn't distort the timeout.
((
after
.
tv_sec
*
1000
+
after
.
tv_usec
/
1000
)
timeout
=
2000
;
-
(
before
.
tv_sec
*
1000
+
before
.
tv_usec
/
1000
));
rc
=
zmq_setsockopt
(
sb
,
ZMQ_RCVTIMEO
,
&
timeout
,
timeout_size
);
assert
(
elapsed
>
200
&&
elapsed
<
300
);
// Check that normal message flow works as expected
void
*
backend
=
zmq_socket
(
ctx
,
ZMQ_DEALER
);
assert
(
backend
);
rc
=
zmq_connect
(
backend
,
"inproc://timeout_test"
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
pthread_t
thread
;
rc
=
zmq_setsockopt
(
backend
,
ZMQ_SNDTIMEO
,
&
timeout
,
sizeof
(
int
));
rc
=
pthread_create
(
&
thread
,
NULL
,
worker
,
ctx
);
assert
(
rc
==
0
);
watch
=
zmq_stopwatch_start
();
rc
=
zmq_recv
(
sb
,
buf
,
32
,
0
);
assert
(
rc
==
-
1
);
assert
(
zmq_errno
()
==
EAGAIN
);
elapsed
=
zmq_stopwatch_stop
(
watch
);
assert
(
elapsed
>
1900000
&&
elapsed
<
2100000
);
rc
=
pthread_join
(
thread
,
NULL
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
// Check that timeouts don't break normal message transfer.
rc
=
zmq_send
(
backend
,
"Hello"
,
5
,
0
);
void
*
sc
=
zmq_socket
(
ctx
,
ZMQ_PUSH
);
assert
(
rc
==
5
);
assert
(
sc
);
rc
=
zmq_recv
(
frontend
,
buffer
,
32
,
0
);
rc
=
zmq_setsockopt
(
sb
,
ZMQ_RCVTIMEO
,
&
timeout
,
timeout_size
);
assert
(
rc
==
5
);
assert
(
rc
==
0
);
rc
=
zmq_setsockopt
(
sb
,
ZMQ_SNDTIMEO
,
&
timeout
,
timeout_size
);
assert
(
rc
==
0
);
rc
=
zmq_connect
(
sc
,
"inproc://timeout_test"
);
assert
(
rc
==
0
);
rc
=
zmq_send
(
sc
,
buf
,
32
,
0
);
assert
(
rc
==
32
);
rc
=
zmq_recv
(
sb
,
buf
,
32
,
0
);
assert
(
rc
==
32
);
// Clean-up
.
// Clean-up
rc
=
zmq_close
(
sc
);
rc
=
zmq_close
(
backend
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_close
(
sb
);
rc
=
zmq_close
(
frontend
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
rc
=
zmq_term
(
ctx
);
rc
=
zmq_ctx_term
(
ctx
);
assert
(
rc
==
0
);
assert
(
rc
==
0
);
return
0
;
return
0
;
}
}
tests/testutil.hpp
View file @
b60689e5
...
@@ -24,11 +24,11 @@
...
@@ -24,11 +24,11 @@
#include "../include/zmq.h"
#include "../include/zmq.h"
#include <string.h>
#include <string.h>
#undef NDEBUG
#undef NDEBUG
#include <assert.h>
#include <assert.h>
inline
void
bounce
(
void
*
sb
,
void
*
sc
)
static
void
bounce
(
void
*
sb
,
void
*
sc
)
{
{
const
char
*
content
=
"12345678ABCDEFGH12345678abcdefgh"
;
const
char
*
content
=
"12345678ABCDEFGH12345678abcdefgh"
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment