zeromq socket recv виси

Използвам zeromq (последна версия, 2012.04.04), c++, ms срещу 2008 (x86 издание/дебъгване), windows 7 x64. Опитвам се да кодирам проста система клиент-сървър.

проблем

Проблемът ми е увисване на компютъра при команда recv() на Windows 7, когато много клиенти се свързват към сървъра едновременно.

При Windows Vista резултатът е като при Windows XP - клиентът има грешка:
http://research.makseq.com/testZMQ/2.Vista.png
http://research.makseq.com/testZMQ/1.PNG
След този отказ клиентите не могат да се свържат със сървъра, те пишат:
„Неуспешно твърдение: Адресът вече се използва: ... "

Ето изходния код:

http://research.makseq.com/testZMQ/testZMQ.rar

Как да използвам:

1) "testZMQ.exe сървър" към стартиране на сървъра,

2) натиснете enter и задръжте в "testZMQ.exe", за да стартирате много-много-много клиенти.

Опитайте да стартирате сървъра няколко пъти: Мисля, че тази грешка се случва, когато сървърът стартира два и повече пъти.

#include "stdafx.h"
#include "../Libraries/zeromq/include/zmq.h"
#include "../Libraries/zeromq/include/zhelpers.hpp"
#include <string>
using namespace std; 

#ifdef WIN32
#pragma comment(lib, "../Libraries/zeromq/libzmq.lib") 
#endif

//-----------------------------------------------------------------------------
int server()
{
    cout << ":: Server ::" << endl;
    zmq::context_t context(1);
    zmq::socket_t server(context, ZMQ_REP);
    server.bind("tcp://*:7774");

    while (1) {

         // receive 
         zmq::message_t messageR;
         cout << "debug point 1" << endl; 
         server.recv(&messageR); // <== dead hanging here
         cout << "debug point 2" << endl; 
         string recieved = string(static_cast<char*>(messageR.data()), messageR.size());

         // send
         string reply = "do something";
         zmq::message_t messageS(reply.size());
         memcpy(messageS.data(), reply.data(), reply.size()); 
         cout << "debug point 3" << endl; 
         server.send(messageS);
         cout << "debug point 4" << endl; 

    }
    return 0;
}

//-----------------------------------------------------------------------------
int client()
{
    cout << ":: Client ::" << endl;
    // connect
    zmq::context_t context(1);
    zmq::socket_t *client = new zmq::socket_t (context, ZMQ_REQ);
    client->connect("tcp://localhost:7774");
    int linger = 0;
    client->setsockopt (ZMQ_LINGER, &linger, sizeof (linger));

    // send
    string reply = "hello";
    zmq::message_t messageS(reply.size());
    memcpy(messageS.data(), reply.data(), reply.size()); 
    client->send(messageS);

    // receive
    zmq::message_t messageR;
    client->recv(&messageR);
    string recieved = string(static_cast<char*>(messageR.data()), messageR.size());

    // close
    client->close();
    delete client;
    zmq_term(&context);

    return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
    if (argc == 2) server(); 
    else client(); 

    return 0;
}

Какво правя грешно?


person Max Tkachenko    schedule 21.04.2012    source източник


Отговори (2)


recv е блокиращо повикване. Докато нещо не се свърже, то ще стои там и ще чака. Това не е увисване без прекъсване, а просто чака връзка.

person OJ.    schedule 21.04.2012
comment
м.. не мога да направя нищо: да преместя мишката, да стартирам която и да е програма или да затворя програмата си. Компютъра ми виси тотално.. - person Max Tkachenko; 22.04.2012
comment
Уау, това звучи като много по-голям проблем от нещо, което ZMQ прави. Пробвал ли си същото на друга машина? Имате ли същия проблем със същия компилиран двоичен файл? Можете ли да публикувате пълния си изходен код? - person OJ.; 22.04.2012
comment
Да, пробвал съм това нещо на други машини! и резултатът е същият: напълно увиснал! Проблемът е да останете с различни компилации: x86 debug, x86 release... - person Max Tkachenko; 22.04.2012
comment
Благодаря за това. Ще го завъртя, когато се прибера. Между другото, опитвали ли сте да обвържете с един интерфейс/IP адрес вместо заместващия знак, за да видите дали това работи? - person OJ.; 23.04.2012
comment
Не, не го пробвам, но мисля, че резултатът ще е еквивалентен :) - person Max Tkachenko; 23.04.2012
comment
Тествах го на Windows XP. НЯМА мъртво прекъсване, но грешката от страна на клиента беше: research.makseq.com/testZMQ/1 .PNG - person Max Tkachenko; 24.04.2012
comment
В Windows Vista резултатът е като в Windows XP (клиентът има грешка): research.makseq .com/testZMQ/2.Vista.png След тази грешка НИКОЙ клиент не може да се свърже със сървъра, те пишат: Assertion fail: Address already in use: ... - person Max Tkachenko; 24.04.2012

Грешката „Адресът вече се използва“ изглежда означава, че вашето извикване на socket.bind() се случва многократно – т.е. изпълнявате повече от един сървърен процес. Можете да се свържете само веднъж към даден порт на даден интерфейс.

Съмнявам се, че това обяснява защо кара машината да виси, но...

person SteveLove    schedule 16.07.2013