Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gSOAP Chaining C++ Server Classes to Accept Messages on the Same Port Not Working

We have six WSDLs compiled within the same project, and due to some limits of hardware we can only open one port for listening.

For doing this, we choose the approach described by chapter 7.2.8 How to Chain C++ Server Classes to Accept Messages on the Same Port in this gSOAP Manual.

However, when using this approach in we encounter many sever issues:

1. If lots of requests arrive concurrently, then sometimes soap_begin_serve reports error with error=-1, socket is closed immediately by soap server after it is established

2. If we call xxx.destory() after soap_free_stream(), then soap_accept() will report an error of bad file descriptor and not work anymore (solved)

Anybody knows what are the reasons of above phoenomenon? How to solve them?
Our code is very close to the example except a few changes, see below section.

//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;
 }       
like image 620
Wallace Avatar asked Oct 30 '22 23:10

Wallace


1 Answers

Finally I found the reason why some connections were closed by the server rightly after they were established.

It's not the gSOAP server's fault, it's because all connections were coming from a same machine, these clients were set up to reuse address and port reuse caused this problem.

like image 60
Wallace Avatar answered Nov 15 '22 05:11

Wallace