cppzmq icon indicating copy to clipboard operation
cppzmq copied to clipboard

when i send it will show "Resource temporarily unavailable"

Open adadKKKX opened this issue 2 years ago • 3 comments

Hello. i'm using req/resp.

Env

it works on windows10 (req) & Ubuntu Port Binoic (Resp) (armv8) the same code is worked on yesterday .but now it does not work. ,the zppzmq version is same 425

Problem

when i send ,it return "Resource temporarily unavailable" all device

Code

protobuf script

https://paste.ubuntu.org.cn/4545606

Req


zmq::context_t context(1);

zmq::socket_t  Reqer(context, zmq::socket_type::req);


void NetServer::TNetStart(u_short *port)
{
    //CLog netlog = Settings::GetInstance()->Logger_NetWork;
    
    auto Req
        = std::make_shared<NetMsg::ReqHeader>();

    auto Cor
        = std::make_shared<NetMsg::PubSub_Coordinate>();
    //spy all events
    

    std::cout << std::get<0>(zmq::version()) << std::endl;
    std::cout << std::get<1>(zmq::version()) << std::endl;
    std::cout << std::get<2>(zmq::version()) << std::endl;
   // netlog.printf("[%s:%d]NetServer::TNetStart zmq->subscriber", __FILE__, __LINE__);
    //netlog.printf("binding local 1025");
    try
    {
        Reqer.connect("tcp://192.168.191.2:1025");
    }
    catch (const std::exception& e)
    {
        // the connect is successful
        std::cout << "err:" << e.what() << std::endl;
    }
    
    //netlog.printf("connecting remote tcp://192.168.191.2:1025");
   // netlog.printf("waiting info (loop)");
    while (true)
    {
        
        zmq::message_t recvmessage;
        zmq::message_t sendmessage;
        
        // this is protobuf .i thought it is good
        Req->set_cmd_code(0);
        Req->set_cmd_dat_len(0);
        Req->set_cmd_type(NetMsg::MsgType::Dat);

        sendmessage.rebuild(Req->ByteSizeLong());
        Req->SerializeToArray(sendmessage.data(), sendmessage.size());

        
        Reqer.send(sendmessage, zmq::send_flags::none);// it print "Resource temporarily unavailable"!!!!!!!!!!!!!!!!
       
        Reqer.recv(recvmessage, zmq::recv_flags::none);

        Cor->ParseFromArray(recvmessage.data(), recvmessage.size());

        Settings::GetInstance()->SetRobotAtt(Robot1, Cor->ix(), Cor->iy(), Cor->iyaw());


        Sleep(1);

    }
}

resp



// it works on a non-blocking thread 
void NetDispatch()
{
    auto pReqHeader
        = std::make_shared<NetMsg::ReqHeader>();
        
    auto pCorInfo = std::make_shared<NetMsg::PubSub_Coordinate>();
    std::cout << "bind 1025\r\n" ;
    Resp.bind("tcp://*:1025");
        std::cout << std::get<0>(zmq::version()) << std::endl;
    std::cout << std::get<1>(zmq::version()) << std::endl;
    std::cout << std::get<2>(zmq::version()) << std::endl;
    while(true)
    {
        zmq::message_t recvmsg;
        
        std::cout << "waiting \r\n" ;
        Resp.recv(&recvmsg);
        printf("%s\r\n",zmq_strerror(zmq_errno()));// it print "Resource temporarily unavailable"!!!!!!!!!!!!!!!!
        std::cout << "recv \r\n" ;
        pReqHeader->ParseFromArray(recvmsg.data(),recvmsg.size());
        //pReqHeader->PrintDebugString();

        pCorInfo->set_ix(g_Pose.iX);
        pCorInfo->set_iy(g_Pose.iY);
        pCorInfo->set_iyaw(g_Pose.iYaw/10.f);

        //pCorInfo->PrintDebugString();
        zmq::message_t message(pCorInfo->ByteSizeLong());
        pCorInfo->SerializeToArray(message.data(),pCorInfo->ByteSizeLong());
        pCorInfo->PrintDebugString();
        Resp.send(message);
        
        usleep(20000);
    }


}


%%

i thought i does not require it work on non-block. so i can't understand this problem . maybe this is bug!

adadKKKX avatar Mar 13 '22 02:03 adadKKKX

I had the same problem with version 4.9.0. From the source code it seems that in case of error it throws an exception and if everything works fine it returns the number of read bytes. So, my understanding is that we should not check for the errno but handle the exception if they are thrown. What I don't understand is why it's marked with NODISCARD, it feels like the returned number of bytes can be safely ignored.

It would be nice if those details were better documented.

btw here are the relevant code:

    ZMQ_NODISCARD
    recv_result_t recv(message_t &msg, recv_flags flags = recv_flags::none)
    {
        const int nbytes =
          zmq_msg_recv(msg.handle(), _handle, static_cast<int>(flags));
        if (nbytes >= 0) {
            assert(msg.size() == static_cast<size_t>(nbytes));
            return static_cast<size_t>(nbytes);
        }
        if (zmq_errno() == EAGAIN)
            return {};
        throw error_t();

stkw0 avatar Nov 24 '22 14:11 stkw0

If there is no error then I think it will not set errno. But you don't need to check errno at all because either the function is successful (non-null result), or null result (only if non-blocking) or throws an exception.

gummif avatar Nov 25 '22 09:11 gummif

True, so I guess there is really a bug in some place. I received the same error ("Resource temporarily unavailable") but no exception was thrown and the message was in fact successfully received.

stkw0 avatar Nov 25 '22 13:11 stkw0