Функция "soap_call__" возвращает только последний TCP-пакет в буфере контекста soap - PullRequest
0 голосов
/ 03 апреля 2020

У меня проблема, когда я получаю ответ от веб-службы, которая разбита на множество TCP-пакетов.

  • Создать 'MercuriusService.h'

1) wsdl2h -o MercuriusService.h -t MRJ_typemap.dat - c ./WSDL/provider/MercuriusService.wsdl

2) Добавить поддержку WS-Security в разделе «Импорт» MercuriusService.h

#import "wsse.h"  // wsse = <http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd>
  • Создать C код

3) soapcpp2 - c - C MercuriusService.h

Я работаю на C языке, и я являюсь клиентом.

  • Makefile g SOAP ориентированный контент


    INCL = commons.h soapH.h soapStub.h MercuriusServiceSoap12 .nsmap OBJS = soapC .o soapClient.o gsoap / stdsoap2.o gsoap / dom.o \ gsoap / plugin / mecevp.o gsoap / plugin / threads.o gsoap / plugin / smdevp.o gsoap / plugin /wsseapi.o \ commons.o

commons.h и commons.o являются частью моей программы

  • Тестирование программы

Поскольку ответ приходит более В пакете TCP функция "soap_call_xxx" заполняет буфер soap только последним пакетом, как можно увидеть после:

В TEST.log я обнаружил:

...
Read 4344 bytes from socket=5/fd=0
Read count=4344 (+4344)
...
Read 999 bytes from socket=5/fd=0
Read count=5343 (+999)
...

И в журнале моего клиента я получаю "soap_call__xxx" в буфере soap:

2020-04-03 12:52:27 - TST_MERCURJUS - from commons_request (thread 00000)

000 : X6F X6E X2F X3E X3C X6E X73 X34 X3A X45 X78 X61 X6D X69 X6E X61  | on/><ns4:Examina
016 : X74 X69 X6F X6E X43 X6F X6D X6D X65 X6E X74 X73 X2F X3E X3C X2F  | tionComments/></
032 : X6E X73 X34 X3A X45 X78 X61 X6D X49 X6E X66 X6F X3E X3C X6E X73  | ns4:ExamInfo><ns
048 : X34 X3A X45 X78 X61 X6D X49 X6E X66 X6F X3E X3C X6E X73 X34 X3A  | 4:ExamInfo><ns4:
064 : X45 X76 X6F X6C X75 X74 X69 X6F X6E X4E X75 X6D X62 X65 X72 X3E  | EvolutionNumber>
080 : X32 X32 X3C X2F X6E X73 X34 X3A X45 X76 X6F X6C X75 X74 X69 X6F  | 22</ns4:Evolutio
096 : X6E X4E X75 X6D X62 X65 X72 X3E X3C X6E X73 X34 X3A X45 X78 X61  | nNumber><ns4:Exa
112 : X6D X4E X75 X6D X62 X65 X72 X3E X33 X3C X2F X6E X73 X34 X3A X45  | mNumber>3</ns4:E
128 : X78 X61 X6D X4E X75 X6D X62 X65 X72 X3E X3C X6E X73 X34 X3A X52  | xamNumber><ns4:R
144 : X65 X73 X75 X6C X74 X4E X75 X6D X62 X65 X72 X3E X31 X3C X2F X6E  | esultNumber>1</n
160 : X73 X34 X3A X52 X65 X73 X75 X6C X74 X4E X75 X6D X62 X65 X72 X3E  | s4:ResultNumber>
176 : X3C X6E X73 X34 X3A X45 X78 X61 X6D X44 X61 X74 X65 X3E X32 X30  | <ns4:ExamDate>20
192 : X31 X39 X2D X30 X37 X2D X30 X32 X3C X2F X6E X73 X34 X3A X45 X78  | 19-07-02</ns4:Ex
208 : X61 X6D X44 X61 X74 X65 X3E X3C X6E X73 X34 X3A X45 X78 X61 X6D  | amDate><ns4:Exam
224 : X69 X6E X61 X74 X69 X6F X6E X54 X79 X70 X65 X3E X4D X3C X2F X6E  | inationType>M</n
240 : X73 X34 X3A X45 X78 X61 X6D X69 X6E X61 X74 X69 X6F X6E X54 X79  | s4:ExaminationTy
256 : X70 X65 X3E X3C X6E X73 X34 X3A X45 X78 X61 X6D X69 X6E X61 X74  | pe><ns4:Examinat
272 : X69 X6F X6E X52 X65 X73 X75 X6C X74 X3E X34 X3C X2F X6E X73 X34  | ionResult>4</ns4
288 : X3A X45 X78 X61 X6D X69 X6E X61 X74 X69 X6F X6E X52 X65 X73 X75  | :ExaminationResu
304 : X6C X74 X3E X3C X6E X73 X34 X3A X43 X6F X6E X64 X69 X74 X69 X6F  | lt><ns4:Conditio
320 : X6E X61 X6C X52 X65 X69 X6E X73 X74 X61 X74 X65 X6D X65 X6E X74  | nalReinstatement
336 : X44 X75 X72 X61 X74 X69 X6F X6E X2F X3E X3C X6E X73 X34 X3A X45  | Duration/><ns4:E
352 : X78 X61 X6D X69 X6E X61 X74 X69 X6F X6E X43 X6F X6D X6D X65 X6E  | xaminationCommen
368 : X74 X73 X2F X3E X3C X2F X6E X73 X34 X3A X45 X78 X61 X6D X49 X6E  | ts/></ns4:ExamIn
384 : X66 X6F X3E X3C X6E X73 X34 X3A X45 X78 X61 X6D X49 X6E X66 X6F  | fo><ns4:ExamInfo
400 : X3E X3C X6E X73 X34 X3A X45 X76 X6F X6C X75 X74 X69 X6F X6E X4E  | ><ns4:EvolutionN
416 : X75 X6D X62 X65 X72 X3E X32 X32 X3C X2F X6E X73 X34 X3A X45 X76  | umber>22</ns4:Ev
432 : X6F X6C X75 X74 X69 X6F X6E X4E X75 X6D X62 X65 X72 X3E X3C X6E  | olutionNumber><n
448 : X73 X34 X3A X45 X78 X61 X6D X4E X75 X6D X62 X65 X72 X3E X34 X3C  | s4:ExamNumber>4<
464 : X2F X6E X73 X34 X3A X45 X78 X61 X6D X4E X75 X6D X62 X65 X72 X3E  | /ns4:ExamNumber>
480 : X3C X6E X73 X34 X3A X52 X65 X73 X75 X6C X74 X4E X75 X6D X62 X65  | <ns4:ResultNumbe
496 : X72 X3E X31 X3C X2F X6E X73 X34 X3A X52 X65 X73 X75 X6C X74 X4E  | r>1</ns4:ResultN
512 : X75 X6D X62 X65 X72 X3E X3C X6E X73 X34 X3A X45 X78 X61 X6D X44  | umber><ns4:ExamD
528 : X61 X74 X65 X3E X32 X30 X31 X39 X2D X30 X37 X2D X30 X32 X3C X2F  | ate>2019-07-02</
544 : X6E X73 X34 X3A X45 X78 X61 X6D X44 X61 X74 X65 X3E X3C X6E X73  | ns4:ExamDate><ns
560 : X34 X3A X45 X78 X61 X6D X69 X6E X61 X74 X69 X6F X6E X54 X79 X70  | 4:ExaminationTyp
576 : X65 X3E X53 X3C X2F X6E X73 X34 X3A X45 X78 X61 X6D X69 X6E X61  | e>S</ns4:Examina
592 : X74 X69 X6F X6E X54 X79 X70 X65 X3E X3C X6E X73 X34 X3A X45 X78  | tionType><ns4:Ex
608 : X61 X6D X69 X6E X61 X74 X69 X6F X6E X52 X65 X73 X75 X6C X74 X3E  | aminationResult>
624 : X34 X3C X2F X6E X73 X34 X3A X45 X78 X61 X6D X69 X6E X61 X74 X69  | 4</ns4:Examinati
640 : X6F X6E X52 X65 X73 X75 X6C X74 X3E X3C X6E X73 X34 X3A X43 X6F  | onResult><ns4:Co
656 : X6E X64 X69 X74 X69 X6F X6E X61 X6C X52 X65 X69 X6E X73 X74 X61  | nditionalReinsta
672 : X74 X65 X6D X65 X6E X74 X44 X75 X72 X61 X74 X69 X6F X6E X2F X3E  | tementDuration/>
688 : X3C X6E X73 X34 X3A X45 X78 X61 X6D X69 X6E X61 X74 X69 X6F X6E  | <ns4:Examination
704 : X43 X6F X6D X6D X65 X6E X74 X73 X2F X3E X3C X2F X6E X73 X34 X3A  | Comments/></ns4:
720 : X45 X78 X61 X6D X49 X6E X66 X6F X3E X3C X6E X73 X34 X3A X50 X56  | ExamInfo><ns4:PV
736 : X4E X75 X6D X62 X65 X72 X3E X41 X4E X2F X41 X2F X39 X30 X2F X4C  | Number>AN/A/90/L
752 : X42 X2F X34 X39 X38 X33 X35 X30 X2F X32 X30 X31 X38 X3C X2F X6E  | B/498350/2018</n
768 : X73 X34 X3A X50 X56 X4E X75 X6D X62 X65 X72 X3E X3C X6E X73 X34  | s4:PVNumber><ns4
784 : X3A X4C X69 X66 X65 X4C X6F X6E X67 X49 X6E X64 X69 X63 X61 X74  | :LifeLongIndicat
800 : X6F X72 X3E X30 X3C X2F X6E X73 X34 X3A X4C X69 X66 X65 X4C X6F  | or>0</ns4:LifeLo
816 : X6E X67 X49 X6E X64 X69 X63 X61 X74 X6F X72 X3E X3C X6E X73 X34  | ngIndicator><ns4
832 : X3A X44 X65 X73 X63 X72 X69 X70 X74 X69 X6F X6E X43 X6F X64 X65  | :DescriptionCode
848 : X3E X30 X34 X3C X2F X6E X73 X34 X3A X44 X65 X73 X63 X72 X69 X70  | >04</ns4:Descrip
864 : X74 X69 X6F X6E X43 X6F X64 X65 X3E X3C X6E X73 X34 X3A X41 X70  | tionCode><ns4:Ap
880 : X70 X65 X61 X6C X49 X6E X64 X69 X63 X61 X74 X6F X72 X3E X30 X3C  | pealIndicator>0<
896 : X2F X6E X73 X34 X3A X41 X70 X70 X65 X61 X6C X49 X6E X64 X69 X63  | /ns4:AppealIndic
912 : X61 X74 X6F X72 X3E X3C X2F X6E X73 X34 X3A X69 X6E X66 X72 X61  | ator></ns4:infra
928 : X63 X74 X69 X6F X6E X49 X6E X66 X6F X3E X3C X2F X6E X73 X33 X3A  | ctionInfo></ns3:
944 : X69 X6E X66 X6F X3E X3C X2F X6E X73 X33 X3A X46 X69 X6E X64 X49  | info></ns3:FindI
960 : X6E X66 X6F X52 X65 X73 X70 X6F X6E X73 X65 X3E X3C X2F X65 X6E  | nfoResponse></en
976 : X76 X3A X42 X6F X64 X79 X3E X3C X2F X73 X6F X61 X70 X3A X45 X6E  | v:Body></soap:En
992 : X76 X65 X6C X6F X70 X65 X3E _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _  | velope>

Это точно количество байтов второго TCP-пакета !!!

Здесь код части моей программы, обрабатывающей SOAP запросы:

#include <ctype.h>
#include "decap/structs.h"
#include "decap/tcp_threads.h"
#include "gpi_tools.h"
#include "mecevp.h"
#include "smdevp.h"
#include "wsseapi.h"
#include "soapH.h"
#include "MercuriusServiceSoap12.nsmap"
#include "commons.h"

const char  soap_action_find_info[] = "findInfo";
const char  soap_action_find_user[] = "findUser";
const char  *soap_action[] = { soap_action_find_info, soap_action_find_info, soap_action_find_user };

...

int commons_request( tcp_thread *me, char *request, char *soap_endpoint, char *pem_file )
{
    int                             i;
    int                             params_len;
    FILE                            *fd;
    char                            file_spec[192];
    EVP_PKEY                    *rsa_private_key = NULL;
    char                            *indicator_str;
    char                            *requester_language;
    char                            *datetime;
    rt_request_type     request_type;
    time_t                      cur_time;
    time_t                      req_time;
    dom__Indicator      indicator = dom__Indicator__2;
    int                             soap_status;

    specific_datas      *sd = (specific_datas *)me->specific;

    gpi_file_spec( file_spec, pem_file );
    fd = fopen( file_spec, "r" );
    rsa_private_key = PEM_read_PrivateKey( fd, NULL, NULL, (void *)pem_password );
    fclose( fd );
    params_len = (int)strlen( request );
    for( i = 0; i < params_len; i++ )
        if( request[i] == (sd->request_separator) )
            request[i] = (char)0x00;

/* WS Security */
    soap_init2( &(sd->soap), SOAP_IO_KEEPALIVE, SOAP_XML_CANONICAL|SOAP_IO_KEEPALIVE );

    (sd->soap).connect_timeout = 10;
    (sd->soap).send_timeout = 15;
    (sd->soap).recv_timeout = 15;
    (sd->soap).transfer_timeout = 30;

    soap_register_plugin( &(sd->soap), soap_wsse );
    soap_wsse_add_Security( &(sd->soap) );
    soap_wsse_add_BinarySecurityTokenPEM( &(sd->soap), "X509Token", file_spec );
    soap_wsse_add_KeyInfo_SecurityTokenReferenceX509( &(sd->soap), "#X509Token" );
    soap_wsse_sign_body( &(sd->soap), SOAP_SMD_SIGN_RSA_SHA1, rsa_private_key, 0 );

/* SSL management */
    soap_ssl_init();
    soap_ssl_client_context( &(sd->soap), SOAP_SSL_DEFAULT, file_spec, pem_password, NULL, NULL, NULL );

/* Building request */

    time( &cur_time );

    (sd->requester).nationalNumber = (char *)requester_national_number[(sd->request_mode)];
    req_time = cur_time;

    switch( toupper( request[0] ) )
    {
        case 'R':
            request_type = rt_nat_nbr;
            break;

        case 'M':
            request_type = rt_mach_site;
            break;

        case 'N':
            request_type = rt_name_birth;
            break;

        default:
            request_type = rt_invalid;
    }

    indicator_str = request + strlen( request ) + 1;
    switch( indicator_str[0] )
    {
        case '0':
            indicator = dom__Indicator__0;
            break;

        case '1':
            indicator = dom__Indicator__1;
            break;

        case '2':
            indicator = dom__Indicator__2;
            break;

        case '3':
            indicator = dom__Indicator__3;
            break;
    }

    requester_language = indicator_str + strlen( indicator_str ) + 1;
    switch( toupper( requester_language[0] ) )
    {
        case 'F':
            (sd->requester).language = com__Language__FR;
            break;
        case 'N':
            (sd->requester).language = com__Language__NL;
            break;
        case 'D':
            (sd->requester).language = com__Language__DE;
            break;
        case 'E':
            (sd->requester).language = com__Language__EN;
            break;
        default:
            (sd->requester).language = com__Language__XX;
    }

    if( request_type == rt_nat_nbr )
    {
        char        *rrn_number;

        rrn_number = requester_language + strlen( requester_language ) + 1;
        datetime = rrn_number + strlen( rrn_number ) + 1;
        if( strlen( datetime ) > 0 )
            req_time = decap_str_to_time_t( datetime, "%Y-%m-%d" );
        (sd->find_info_request).requester = &(sd->requester);
        (sd->find_info_request).criteria = &(sd->info_criteria);
        (sd->info_criteria).__union_InfoCriteria = 1;
        (sd->info_criteria).union_InfoCriteria.nationalNumberCriteria = &(sd->nationalNumberCriteria);
        (sd->nationalNumberCriteria).__union_NationalNumberCriteria = 1;
        (sd->nationalNumberCriteria).union_NationalNumberCriteria.nationalNumber = rrn_number;
        (sd->info_criteria).infoDateTime = req_time;
        (sd->info_criteria).__sizeindicator = 1;
        (sd->info_criteria).indicator = &indicator;
        soap_status = soap_call___mrj__findInfo(    &(sd->soap), soap_endpoint, soap_action[request_type],
                                                                                            &(sd->find_info_request), &(sd->find_info_response) );
    }
    else if( request_type == rt_mach_site )
    {
        char        *mach_id;
        char        *site_id;

        mach_id = requester_language + strlen( requester_language ) + 1;
        site_id = mach_id + strlen( mach_id ) + 1;
        datetime = site_id + strlen( site_id ) + 1;
        if( strlen( datetime ) > 0 )
            req_time = decap_str_to_time_t( datetime, "%Y-%m-%d" );
        (sd->find_info_request).requester = &(sd->requester);
        (sd->find_info_request).criteria = &(sd->info_criteria);
        (sd->info_criteria).__union_InfoCriteria = 2;
        (sd->info_criteria).union_InfoCriteria.machCriteria = &(sd->machCriteria);
        (sd->machCriteria).machId = mach_id;
        (sd->machCriteria).siteId = site_id;
        (sd->info_criteria).infoDateTime = req_time;
        (sd->info_criteria).__sizeindicator = 1;
        (sd->info_criteria).indicator = &indicator;
        soap_status = soap_call___mrj__findInfo(    &(sd->soap), soap_endpoint, soap_action[request_type],
                                                                                            &(sd->find_info_request), &(sd->find_info_response) );
    }
    else if( request_type == rt_name_birth )
    {
        char        *name;
        char        *firstName;
        char        *birthDate;

        name = requester_language + strlen( requester_language ) + 1;
        firstName = name + strlen( name ) + 1;
        birthDate = firstName + strlen( firstName ) + 1;
        datetime = birthDate + strlen( birthDate ) + 1;
        if( strlen( datetime ) > 0 )
            req_time = decap_str_to_time_t( datetime, "%Y-%m-%d" );
        (sd->find_user_request).requester = &(sd->requester);
        (sd->find_user_request).criteria = &(sd->user_criteria);
        (sd->user_criteria).nameCriteria = &(sd->nameCriteria);
        (sd->nameCriteria).name = name;
        (sd->nameCriteria).firstName = firstName;
        (sd->nameCriteria).birthDate = birthDate;
        (sd->user_criteria).infoDateTime = req_time;
        (sd->user_criteria).__sizeindicator = 1;
        (sd->user_criteria).indicator = &indicator;
        soap_status = soap_call___mrj__findUser(    &(sd->soap), soap_endpoint, soap_action[request_type],
                                                                                            &(sd->find_user_request), &(sd->find_user_response) );
    }
    (sd->soap).buf[(sd->soap).buflen] = (char)0x00;

    return( soap_status );
}

Может ли эта проблема возникать из-за неправильных параметров в "soap_init2"?

Любая помощь приветствуется.

1 Ответ

0 голосов
/ 04 апреля 2020

Полученное сообщение сохраняется в файле RECV.log, когда код компилируется в режиме DEBUG.

Для пояснения схемы буферизации механизм XML g soap не сохраняет все полученное сообщение. в буфере. Скорее, по соображениям производительности, механизм и сгенерированный код постепенно десериализуют входящие сообщения, считывая блок данных за раз. Предыдущее чтение данных отбрасывается из буфера.

Это видно, когда вы смотрите на TEST.log:

...
Read 4344 bytes from socket=5/fd=0
Read count=4344 (+4344)
...
Read 999 bytes from socket=5/fd=0
Read count=5343 (+999)
...

Каждая операция чтения снова заполняет буфер с минимальной блокировкой. Следовательно, буфер может содержать что угодно, то есть один или несколько пакетов TCP или так мало данных, как один байт. Когда вы сбрасываете буфер в конце сообщения, он содержит только последний полученный TCP-пакет.

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

...