1 现象:问题描述
A局点升级OIA失败,在升级OIA后,全球通充值不成功。
2 关键过程:根本原因分析
OIA使用了消息序列号来一一对应请求消息和应答消息,该消息序列号的数据类型设为int型。
OIA接收请求消息中的消息序列号由3位SCPID和7位对话号组成,3位SCPID作为序列号(序列号为10进制表示的10位数)的高3位10进制数。当SCPID大于214时,就可能导致10位消息序列号的取值超过int型范围(2147483647)。此时,再调用atoi函数,就会导致转换后的消息序列号不可预知。
OIA接收应答消息后,根据对应的消息序列号的前三位(即SCPID),来选择FEP进行消息分发。由于调用atoi导致消息序列号发生变化,此时无法再获取正确的SCPID,最终导致消息无法正确转发。
程序代码如下:
//获取消息序列号
char tmpseqno[10+1];
memset(tmpseqno, 0, 11);
memcpy(tmpseqno, (pSocketItem->Code.content+24), 10);
//转换消息序列号
int scpSeqno,uaspSeqno;
scpSeqno = atoi(tmpseqno);
3 结论:解决方案及效果
消息序列号的数据类型设为double,并且使用atof来转换消息序列号,则消息能够正确转发。
程序代码如下:
//获取消息序列号
char tmpseqno[10+1];
memset(tmpseqno, 0, 11);
memcpy(tmpseqno, (pSocketItem->Code.content+24), 10);
//转换消息序列号
int uaspSeqno;
double scpSeqno;
scpSeqno = atof(tmpseqno);
4 经验总结:预防措施和规范建议
要结合实际的应用,来设计变量的数据类型,并选择相应的转换处理函数。当atoi函数的参数范围超过int型时,将会出现错误。
5 备注
常见的错误还有:在检测整数配置项的取值时,一般也会使用atoi来转换所读取的数值。当实际配置的值超过int型取值范围时,同样也会出错。
6 考核点
使用系统函数时,注意传入参数的范围。
7 试题
1、如下语句:
printf("result1 = %d result2 = %d ", atoi("1111111111"), atoi("2222222222"));
关于打印结果说法正确的是:(B)
A. 打印 result1 = 1111111111 result2 = 2222222222
B. 打印 result1 = 1111111111 result2 结果非2222222222
C. 打印result1为非1111111111 result2 结果为非2222222222
D. 打印 result1 = 1111111111 result2 = 0
阅读(1231) | 评论(0) | 转发(0) |