gSOAP, связывающий классы сервера C++ для приема сообщений на одном и том же порту, не работает

У нас есть шесть WSDL, скомпилированных в рамках одного проекта, и из-за некоторых аппаратных ограничений мы можем открыть только один порт для прослушивания.

Для этого мы выбираем подход, описанный в главе 7.2.8 Как объединить серверные классы C++ в цепочку для приема сообщений на одном и том же порту в этом Руководство по gSOAP.

Однако при использовании этого подхода мы сталкиваемся со многими серьезными проблемами:

<сильный>1. Если одновременно поступает много запросов, то иногда soap_begin_serve сообщает об ошибке с error=-1, сокет сразу же закрывается мыльным сервером после его установки

<сильный>2. Если мы вызовем xxx.destory() после soap_free_stream(), тогда soap_accept() сообщит об ошибке неверного файлового дескриптора и больше не будет работать (решено)

Кто-нибудь знает, каковы причины вышеуказанного явления? Как их решить?
Наш код очень близок к примеру, за исключением нескольких изменений, см. раздел ниже.

//server thread 
Abc::soapABCService server; // generated with soapcpp2 -i -x -n -QAbc

server.bind(NULL, 12345, 100);  
server.soap_mode = SOAP_KEEP_ALIVE | SOAP_UTF_CSTRING;
server.recv_timeout = server.send_timeout = 60;

while (true)
{
    server.accept(); 

    ... 
    pthread_create(&pid, NULL, handle_new_request, server.copy());
 }  // while(true)



 // work thread - the thread function
 void *handle_new_request(void* arg)
 {
    // generated with soapcpp2 -i -x -n -QAbc 
    Abc::soapABCService *abc = (Abc::soapABCService*)arg; 
    Uvw::soapUVWService uvw; // generated with soapcpp2 -i -x -n -QUvw 
    Xyz::soapXYZService xyz; // generated with soapcpp2 -i -x -n -QXyz

    if(soap_begin_serve(abc)) 
    {
        //sometimes it reports error
        //due to unkown reason, socket was closed by soap server 
        abc->soap_stream_fault(std::cerr); 
    }
    else if (abc->dispatch() == SOAP_NO_METHOD) 
    { 
        soap_copy_stream(&uvw, abc);
        uww.state = SOAP_COPY;

        if (uvw.dispatch() == SOAP_NO_METHOD) 
        { 
            soap_copy_stream(&xyz, &uvw); 
            xyz.state = SOAP_COPY;

            if (xyz.dispatch()) 
            { 
                soap_send_fault(&xyz); // send fault to client 
                xyz.soap_stream_fault(std::cerr); 
            } 

            soap_free_stream(&xyz); // free the copy 
            xyz.destroy();
        } 
        else
        { 
            soap_send_fault(&uvw); // send fault to client 
            uvw.soap_stream_fault(std::cerr); 
        }  

        soap_free_stream(&uvw); // free the copy 
        uvw.destroy();
    }
    else if (abc->error)
    {
        abc->soap_stream_fault(std::cerr);
    }
    else
    {

    }

    abc->destroy();
    delete abc;
    abc = NULL;
 }       

person Wallace    schedule 18.07.2015    source источник
comment
Я заметил в вашем коде, что вы используете soap_copy_stream от uvw до xyz, хотя поток xyz уже был освобожден. Можно ли soap_copy_stream использовать службу, которая уже была soap_free_stream удалена?   -  person ssemilla    schedule 18.07.2015
comment
@weavr это может быть проблемой, я пойду проверю свой код   -  person Wallace    schedule 18.07.2015


Ответы (1)


Наконец-то я нашел причину, по которой некоторые соединения закрывались сервером сразу после их установки.

Это не вина сервера gSOAP, это потому, что все соединения исходили с одной и той же машины, эти клиенты были настроены на повторное использование адреса и повторного использования порта, что вызвало эту проблему.

person Wallace    schedule 26.07.2015