Прием сокета ZeroMQ зависает

Я использую zeromq (последняя версия, 2012.04.04), c++, ms vs 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, выпуск x86... - 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 После этого фейла НИ ОДИН клиент не может подключиться к серверу, пишут: Ошибка утверждения: Адрес уже используется: ... - person Max Tkachenko; 24.04.2012

Ошибка «Адрес уже используется», по-видимому, означает, что ваш вызов socket.bind() происходит несколько раз, т.е. вы запускаете более одного серверного процесса. Вы можете только один раз привязаться к данному порту на данном интерфейсе.

Я сомневаюсь, что это объясняет, почему это заставляет машину зависать...

person SteveLove    schedule 16.07.2013