ZMQ push/pull 模式在两个应用程序之间发送消息,但 tcpdump 显示每个数据包的源和目标是相同的
ZMQ push/pull pattern sends messages between two apps but tcpdump shows that source and destination of each packet are the same
我在学习ZMQ
。我创建了两个使用 pull/push 模式相互通信的简单应用程序。我在 Ubuntu 上创建了两个 tap 接口。其中一个的 IP 地址为 1.1.1.1,第二个分路器的 IP 地址为 1.1.1.2。这些应用程序中的每一个都发送一个字符串并写入 stdout
接收到的字符串。一切如我所愿,但是当我 运行 tcpdump
我看到对于每个数据包,源地址和目标地址都是相同的。 tcpdump
还显示 ZMQ
使用我在应用程序中设置的不同端口。
这是我的应用程序 1 的代码:
#include <zmq.hpp>
#include <string>
#include <iostream>
#include <thread>
using namespace std;
using namespace zmq;
int main()
{
context_t zmq_context = context_t();
socket_t zmq_send_socket = socket_t(zmq_context, ZMQ_PUSH);
socket_t zmq_recv_socket = socket_t(zmq_context, ZMQ_PULL);
string push_socat = "tcp://1.1.1.2:5001";
string pull_socat = "tcp://1.1.1.1:5000";
zmq_send_socket.bind(push_socat.c_str());
zmq_recv_socket.connect(pull_socat.c_str());
while(1)
{
string msg = "app 1 sends";
message_t received_message;
if(msg.size())
{
message_t send_message(msg);
zmq_send_socket.send(send_message, send_flags::dontwait);
}
auto result = zmq_recv_socket.recv(received_message, recv_flags::dontwait);
if (result.has_value())
{
cout<<received_message<<endl;
}
std::this_thread::sleep_for(std::chrono::milliseconds(3000));
}
}
这是我的应用 2 代码:
#include <zmq.hpp>
#include <string>
#include <iostream>
#include <thread>
using namespace std;
using namespace zmq;
int main()
{
context_t zmq_context = context_t();
socket_t zmq_send_socket = socket_t(zmq_context, ZMQ_PUSH);
socket_t zmq_recv_socket = socket_t(zmq_context, ZMQ_PULL);
string push_socat = "tcp://1.1.1.1:5000";
string pull_socat = "tcp://1.1.1.2:5001";
zmq_send_socket.bind(push_socat.c_str());
zmq_recv_socket.connect(pull_socat.c_str());
while(1)
{
string msg = "app 2 sends";
message_t received_message;
if(msg.size())
{
message_t send_message(msg);
zmq_send_socket.send(send_message, send_flags::dontwait);
}
auto result = zmq_recv_socket.recv(received_message, recv_flags::dontwait);
if (result.has_value())
{
cout<<received_message<<endl;
}
std::this_thread::sleep_for(std::chrono::milliseconds(3000));
}
}
应用 1 打印“应用 2 发送”,应用 2 打印“应用 1 发送”。
tcpdump
的示例输出:
22:01:51.724290 00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 77: 10.100.100.1.5000 > 10.100.100.1.45624: Flags [P.], seq 649:660, ack 1, win 512, options [nop,nop,TS val 62388355 ecr 62385355], length 11
22:01:51.724325 00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 66: 10.100.100.1.45624 > 10.100.100.1.5000: Flags [.], ack 660, win 512, options [nop,nop,TS val 62388355 ecr 62388355], length 0
22:01:51.967303 00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 79: 10.100.100.2.5001 > 10.100.100.2.41982: Flags [P.], seq 767:780, ack 1, win 512, options [nop,nop,TS val 2441785963 ecr 2441782963], length 13
22:01:51.967335 00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 66: 10.100.100.2.41982 > 10.100.100.2.5001: Flags [.], ack 780, win 512, options [nop,nop,TS val 2441785963 ecr 2441785963], length 0
22:01:54.724516 00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 77: 10.100.100.1.5000 > 10.100.100.1.45624: Flags [P.], seq 660:671, ack 1, win 512, options [nop,nop,TS val 62391355 ecr 62388355], length 11
22:01:54.724551 00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 66: 10.100.100.1.45624 > 10.100.100.1.5000: Flags [.], ack 671, win 512, options [nop,nop,TS val 62391355 ecr 62391355], length 0
22:01:54.967509 00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 79: 10.100.100.2.5001 > 10.100.100.2.41982: Flags [P.], seq 780:793, ack 1, win 512, options [nop,nop,TS val 2441788963 ecr 2441785963], length 13
22:01:54.967542 00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 66: 10.100.100.2.41982 > 10.100.100.2.5001: Flags [.], ack 793, win 512, options [nop,nop,TS val 2441788963 ecr 2441788963], length 0
你知道为什么源地址和目标地址相同,为什么我能看到奇怪的端口吗?
您获得的结果符合您的端口设置。
如果您查看 bind/connect 端口,您的 push/pull 对套接字都具有相同的 IP 地址。
App1
zmq_send_socket.bind(tcp://1.1.1.2:5001)
App2
zmq_recv_socket.connect(tcp://1.1.1.2:5001);
“奇怪的”端口来自 tcp 连接的连接端。 bind/listen 端使用您指定的端口 (5000/5001),但连接端将使用临时端口。
我在学习ZMQ
。我创建了两个使用 pull/push 模式相互通信的简单应用程序。我在 Ubuntu 上创建了两个 tap 接口。其中一个的 IP 地址为 1.1.1.1,第二个分路器的 IP 地址为 1.1.1.2。这些应用程序中的每一个都发送一个字符串并写入 stdout
接收到的字符串。一切如我所愿,但是当我 运行 tcpdump
我看到对于每个数据包,源地址和目标地址都是相同的。 tcpdump
还显示 ZMQ
使用我在应用程序中设置的不同端口。
这是我的应用程序 1 的代码:
#include <zmq.hpp>
#include <string>
#include <iostream>
#include <thread>
using namespace std;
using namespace zmq;
int main()
{
context_t zmq_context = context_t();
socket_t zmq_send_socket = socket_t(zmq_context, ZMQ_PUSH);
socket_t zmq_recv_socket = socket_t(zmq_context, ZMQ_PULL);
string push_socat = "tcp://1.1.1.2:5001";
string pull_socat = "tcp://1.1.1.1:5000";
zmq_send_socket.bind(push_socat.c_str());
zmq_recv_socket.connect(pull_socat.c_str());
while(1)
{
string msg = "app 1 sends";
message_t received_message;
if(msg.size())
{
message_t send_message(msg);
zmq_send_socket.send(send_message, send_flags::dontwait);
}
auto result = zmq_recv_socket.recv(received_message, recv_flags::dontwait);
if (result.has_value())
{
cout<<received_message<<endl;
}
std::this_thread::sleep_for(std::chrono::milliseconds(3000));
}
}
这是我的应用 2 代码:
#include <zmq.hpp>
#include <string>
#include <iostream>
#include <thread>
using namespace std;
using namespace zmq;
int main()
{
context_t zmq_context = context_t();
socket_t zmq_send_socket = socket_t(zmq_context, ZMQ_PUSH);
socket_t zmq_recv_socket = socket_t(zmq_context, ZMQ_PULL);
string push_socat = "tcp://1.1.1.1:5000";
string pull_socat = "tcp://1.1.1.2:5001";
zmq_send_socket.bind(push_socat.c_str());
zmq_recv_socket.connect(pull_socat.c_str());
while(1)
{
string msg = "app 2 sends";
message_t received_message;
if(msg.size())
{
message_t send_message(msg);
zmq_send_socket.send(send_message, send_flags::dontwait);
}
auto result = zmq_recv_socket.recv(received_message, recv_flags::dontwait);
if (result.has_value())
{
cout<<received_message<<endl;
}
std::this_thread::sleep_for(std::chrono::milliseconds(3000));
}
}
应用 1 打印“应用 2 发送”,应用 2 打印“应用 1 发送”。
tcpdump
的示例输出:
22:01:51.724290 00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 77: 10.100.100.1.5000 > 10.100.100.1.45624: Flags [P.], seq 649:660, ack 1, win 512, options [nop,nop,TS val 62388355 ecr 62385355], length 11
22:01:51.724325 00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 66: 10.100.100.1.45624 > 10.100.100.1.5000: Flags [.], ack 660, win 512, options [nop,nop,TS val 62388355 ecr 62388355], length 0
22:01:51.967303 00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 79: 10.100.100.2.5001 > 10.100.100.2.41982: Flags [P.], seq 767:780, ack 1, win 512, options [nop,nop,TS val 2441785963 ecr 2441782963], length 13
22:01:51.967335 00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 66: 10.100.100.2.41982 > 10.100.100.2.5001: Flags [.], ack 780, win 512, options [nop,nop,TS val 2441785963 ecr 2441785963], length 0
22:01:54.724516 00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 77: 10.100.100.1.5000 > 10.100.100.1.45624: Flags [P.], seq 660:671, ack 1, win 512, options [nop,nop,TS val 62391355 ecr 62388355], length 11
22:01:54.724551 00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 66: 10.100.100.1.45624 > 10.100.100.1.5000: Flags [.], ack 671, win 512, options [nop,nop,TS val 62391355 ecr 62391355], length 0
22:01:54.967509 00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 79: 10.100.100.2.5001 > 10.100.100.2.41982: Flags [P.], seq 780:793, ack 1, win 512, options [nop,nop,TS val 2441788963 ecr 2441785963], length 13
22:01:54.967542 00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 66: 10.100.100.2.41982 > 10.100.100.2.5001: Flags [.], ack 793, win 512, options [nop,nop,TS val 2441788963 ecr 2441788963], length 0
你知道为什么源地址和目标地址相同,为什么我能看到奇怪的端口吗?
您获得的结果符合您的端口设置。
如果您查看 bind/connect 端口,您的 push/pull 对套接字都具有相同的 IP 地址。
App1
zmq_send_socket.bind(tcp://1.1.1.2:5001)
App2
zmq_recv_socket.connect(tcp://1.1.1.2:5001);
“奇怪的”端口来自 tcp 连接的连接端。 bind/listen 端使用您指定的端口 (5000/5001),但连接端将使用临时端口。