gsoap - “soap_call__”函数只返回soap上下文缓冲区中的最后一个TCP数据包
问题描述
当我从分成许多 TCP 数据包的 WEB 服务中得到答案时,我遇到了一个问题。
- 创建“MercuriusService.h”
1) wsdl2h -o MercuriusService.h -t MRJ_typemap.dat -c ./WSDL/provider/MercuriusService.wsdl
2) 在 MercuriusService.h 的“Import”部分添加 WS-Security 支持
#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 面向 gSOAP 的内容
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”函数仅使用最后一个数据包填充肥皂缓冲区,如下所示:
在 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”:
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”中的错误参数吗?
欢迎任何帮助。
解决方案
在 DEBUG 模式下编译代码时,收到的消息将保存到 RECV.log。
为了阐明缓冲方案,gsoap 的 XML 引擎不会将接收到的整个消息存储在缓冲区中。相反,出于性能原因,引擎和生成的代码通过一次读取一个数据块来递增地反序列化入站消息。从缓冲区中丢弃先前读取的数据。
当您查看 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 数据包。
这种增量解析和反序列化的方法是有效的,因为反序列化器可以在第一个数据包到达时立即启动。
推荐阅读
- apache-spark - 按其 95% 和 5% 的值裁剪 Spark DataFrame 列
- file - 如何在获取列表后在 shell 脚本中开始循环之前添加延迟
- t4 - 我如何在另一个 T4 文件中使用 T4 模板文件
- c# - 以编程方式禁用任务管理器 (ctrl+alt+del)
- python - 如何(手动)编辑元素树的xml格式
- arrays - 在 ruby 中使用 spaceship 运算符进行自定义排序
- scala - 为什么不能将元素附加到列表中
- unit-testing - JUnit 避免重复断言
- json - 用jq替换基于键值对的JSON值
- python - 使用python从csv数据生成一个新的xml