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;
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With