我想要一对独占的 2 个套接字,以允许 2 个独立应用程序之间进行双边通信。我使用 ZeroMQ
cppzmq
。
在客户端中,我通过握手检查服务器是否处于活动状态。 当我启动客户端时,可能会出现服务器尚未在线的情况。 这会导致客户端此时挂起,我需要强制退出应用程序。
我正在尝试在客户端实现超时,在未收到握手 OK 消息后退出应用程序。我想我可以用
ZMQ_CONNECT_TIMEOUT
、ZMQ_SNDTIMEO
或 ZMQ_RCVTIMEO
来做到这一点。不幸的是,这并没有按照我的预期工作,客户端在程序结束时一直挂起。
如何在程序返回时停止所有阻塞操作?请注意,这是一个 MVCE,我正在一个更大的应用程序中运行它。因此,简单地检查
if (incoming_msg != "OK") exit(0);
在这里可以工作,但不是一个有用的解决方案。
服务器:
// server.cpp
#include <iostream>
#include <zmq.hpp>
int main()
{
zmq::context_t context(1);
zmq::socket_t socket(context, zmq::socket_type::pair);
socket.bind("tcp://*:5555");
while (true)
{
zmq::message_t incoming;
auto ret = socket.recv(incoming, zmq::recv_flags::none);
std::string incoming_str = incoming.to_string();
std::cout << "Received request: " << incoming_str << std::endl;
if (incoming_str == "connected")
{
std::cout << " Sending OK" << std::endl;
zmq::message_t ack(2);
memcpy(ack.data(), "OK", 2);
socket.send(ack, zmq::send_flags::none);
}
}
return 0;
}
客户:
// client.cpp
#include <iostream>
#include <zmq.hpp>
int main()
{
zmq::context_t context(1);
zmq::socket_t socket(context, zmq::socket_type::pair);
int timeout_ms = 100;
socket.setsockopt(ZMQ_CONNECT_TIMEOUT, timeout_ms);
socket.setsockopt(ZMQ_SNDTIMEO, timeout_ms);
socket.setsockopt(ZMQ_RCVTIMEO, timeout_ms);
socket.connect("tcp://localhost:5555");
// send "connected"
zmq::message_t msg(9);
memcpy(msg.data(), "connected", 9);
socket.send(msg, zmq::send_flags::none);
// receive "OK"
zmq::message_t incoming;
auto ret = socket.recv(incoming, zmq::recv_flags::none);
std::string incoming_str = incoming.to_string();
std::cout << "Received from server: " << incoming_str << std::endl;
return 0;
}
“如何在程序返回时停止所有阻塞操作”
然后你有责任处理未阻塞的recv并关闭套接字。 检查返回值,如果其 ==
ETERM
则关闭套接字。那时(如果所有套接字都关闭)zmq::context 将解除阻止/继续,并且您的应用程序将退出。