Hi, I wrote a client/server application using SOAP to exchange messages. The client code is pasted as below. All other files are generated by wsdl2h and soapcpp2. Each time, the client reads a message from an XML file, sends it to the server, gets a response, then it tries to send another message of different type. I tried to reuse the runtime context, in this case, "ads_service", but it caused segmentation fault, when the client tries to send the second message in the same loop. As you may notice, I use a separate runtime context "localContext" to read XML files. All because I cannot reuse the same runtime context.
Can anyone point out what is wrong with my code? Thank you! Gao File AdmStub.h: class AdmStub { public: const static int NUM_PLACEMENTS = 3; public: adm__PlacementRequestType* GetPlacementRequest(struct soap* context, const char* xmlFileName); int ProcessPlacementResponse(struct soap* context, adm__PlacementResponseType* response); adm__PlacementStatusNotificationType* GetPlacementStatusNotification(struct soap* context, const char* xmlFileName); }; File AdmStub.cpp: #include <fstream> #include <unistd.h> #include "soapADSBindingProxy.h" #include "ADSBinding.nsmap" #include "AdmStub.h" int main() { AdmStub admStub; for (int i = 0; i < AdmStub::NUM_PLACEMENTS; i++) { ADSBindingProxy ads_service; // Generate a placement request struct soap* localContext = soap_new(); soap_begin(localContext); adm__PlacementRequestType* placementRequest = admStub.GetPlacementRequest(localContext, "placementReq.xml"); adm__PlacementResponseType* placementResponse = soap_new_adm__PlacementResponseType(&ads_service, -1); // Don't pass NULL. // Call web service if (ads_service.placementRequest(placementRequest, placementResponse) == SOAP_OK) { if (admStub.ProcessPlacementResponse(&ads_service, placementResponse) == 0) { } else { // error } } else { ads_service.soap_stream_fault(std::cerr); } soap_destroy(localContext); soap_end(localContext); ads_service.destroy(); // sleep usleep(2000); // send a placement status notification adm__PlacementStatusNotificationType* statusNotification = admStub.GetPlacementStatusNotification(localContext, "placementStatus.xml"); adm__PlacementStatusAcknowledgementType* statusArknowlegement = soap_new_adm__PlacementStatusAcknowledgementType(&ads_service, -1); if (ads_service.placementStatus(statusNotification, statusArknowlegement) == SOAP_OK) { } else { ads_service.soap_stream_fault(std::cerr); } soap_destroy(localContext); soap_end(localContext); soap_done(localContext); soap_free(localContext); ads_service.destroy(); } return 0; } adm__PlacementRequestType* AdmStub::GetPlacementRequest(struct soap* context, const char* xmlFileName) { adm__PlacementRequestType *aPlaceReq = NULL; std::fstream fileStream; fileStream.open(xmlFileName, std::fstream::in); if (fileStream.good()) { context->is = &fileStream; soap_begin_recv(context); if ((aPlaceReq = soap_get_adm__PlacementRequestType(context, NULL, NULL, NULL)) == NULL) { std::cout << "Error in deserializing the input." << std::endl; } soap_end_recv(context); fileStream.close(); } else { std::cout << "Error in opening XML file." << std::endl; } return aPlaceReq; } int AdmStub::ProcessPlacementResponse(struct soap* context, adm__PlacementResponseType* response) { int result = 0; if (response != NULL) { // Process std::fstream fileStream; fileStream.open("placementResp.xml", std::fstream::out); if (fileStream.good()) { context->os = &fileStream; soap_begin_send(context); response->soap_serialize(context); response->soap_put(context, "PlacementResponse", NULL); soap_end_send(context); fileStream.close(); } else { result = -1; std::cout << "Error in opening XML file." << std::endl; } } else { result = -1; std::cout << "Response is NULL" << std::endl; } return result; } adm__PlacementStatusNotificationType* AdmStub::GetPlacementStatusNotification(struct soap* context, const char* xmlFileName) { adm__PlacementStatusNotificationType *aNotification = NULL; std::fstream fileStream; fileStream.open(xmlFileName, std::fstream::in); if (fileStream.good()) { context->is = &fileStream; soap_begin_recv(context); if ((aNotification = soap_get_adm__PlacementStatusNotificationType(context, NULL, NULL, NULL)) == NULL) { std::cout << "Error in deserializing the input." << std::endl; } soap_end_recv(context); fileStream.close(); } else { std::cout << "Error in opening XML file." << std::endl; } return aNotification; }