本文主要讲述了Socket协议脚本的基础知识和编写方法,让大家能够在短时间内快速掌握简单的Socket协议脚本的编写方法。
1.socket协议介绍
Socket协议有万能协议之称,很多系统底层都是用的socket协议,用处十分广泛。
1.1 Socket通讯方式说明
与socket通讯有两种方式,一种是建立长连接,建立后不停的发送,接收;另一种是建立短连接,即建立连接发送报文,接收报文关闭连接
1.2 Socket协议发送的buf类型介绍
Send buffer类型分为字符串和xml类型
1.3 Socket协议脚本编写前提:
与项目组沟通,确认是否是socket协议,由项目组提供服务器IP和端口号还有socket协议交易的报文发送及接收报文对,及交易接口文档,了解清楚报文的数据长度,参数化字段,结构,代表什么等,了解清楚后进行socket协议脚本的开发。
1.4、Socket协议脚本函数说明及实例:
1)名称 lrs_create_socket();
创建socket连接,添加IP和端口号,如果创建成功返回值为0,反之则返回为非0数值。(对于长连接,建立socket连接放在vuser_init函数中,短连接放在Action中即可) 实例: lrs_create_socket(\"socket0\",\"TCP\",\"RemoteHost=180.170.150.230:7700\", LrsLastArg);
2)名称 lrs_send();
发送socket请求消息,取缓冲区buf0的报文并发送。
实例: lrs_send(\"socket0\",\"buf1\",LrsLastArg);
3)名称 lrs_receive();
接收socket的响应报文,放置buf1中。
实例:lrs_receive(\"socket0\",\"buf2\",LrsLastArg);
4)名称 lrs_get_last_received_buffer();
获取最后收到的buffer和大小,其中将最后收到的buffer的值赋给RecvBuf变量,将大小赋值给RecvLen。
实例: lrs_get_last_received_buffer(\"socket0\",&recvBuf,&recvLen);
5)名称 lrs_free_buffer();
为防止内存泄露,释放内存空间。
实例: lrs_free_buffer(recvBuf);
6)名称 lrs_close_socket();
关闭Socket连接,(对于长连接,关闭socket连接应放在vuser_end函数中)
实例: lrs_close_socket(\"socket0\");
其他常用的Socket函数:
lrs_set_send_buffer(\"socket0\", sSendPkg, iLenOfPkg );//指定要发送的socket信息
lrs_get_buffer_by_name(\"buf0\", sSendPkg, iLenOfPkg);// 获取收到的buffer和大小
lrs_length_send(\"socket0\",\"buf0\",1,\"Size=4\",\"Encoding=1\",LrsLastArg);
关联函数:
lrs_save_param_ex(\"socket0\",\"received\",\"\",151,7,\"ascii\",\"response\");//取指定位置字符串保存到变量,以便判断事务是否成功
lrs_save_searched_string();//在指定位置搜索字符串,将出现的字符串报错到参数中
超时函数
lrs_set_connect_timeout();//设置连接超时时间
lrs_set_recv_timeout();//设置服务器响应超时时间
lrs_set_recv_timeout2();//设置接收超时时间,使系统不去检查回收的内容是否一致
2、Socket脚本编写
2.1 简单划分步骤
这种方法是我无意在一片文章中看到的,总体说来,比较简单。就像把大象放进冰箱一样,总共分三步:
第一步:把冰箱门打开
//建立到服务端的连接
rc = lrs_create_socket(\"socket0\", \"TCP\", \"LocalHost=0\", \"RemoteHost=128.64.64.23:8988\", LrsLastArg);
if (rc==0)
lr_output_message(\"Socket was successfully created \");
else
lr_output_message(\"An error occurred while creating the socket, Error Code: %d\", rc);
第二步:把大象装进去
lrs_send(\"socket0\", \"buf0\", LrsLastArg); //往\"socket0\"发送\"buf0\"中的数据
lrs_receive(\"socket0\", \"buf1\", LrsLastArg);//将\"socke0\"中返回的数据存放到\"buf1\"中
第三步:把冰箱门带上
//关闭连接
lrs_close_socket(\"socket0\");
2.2 详细划分步骤
◇变量的声明与定义
◇ 创建socket连接
◇ 发送socket请求
◇ 接收socket响应
◇ 从返回Buffer 中抽取结果
◇ 结果判断
◇ 释放内存
◇ 断开连接。
2.3 实例脚本
下面我们就是用一个实际项目不同报文格式的脚本进行讲解;
若项目是短连接,且报文不是从文件中读取信息时,vuser_init和vuser_end部分默认即可,主要在Action中开发测试脚本和在data.ws中传输数据到Action的代码中。
Vuser_init.c
#include \"lrs.h\" vuser_init() { lrs_startup(257); return 0; } |
Action.c
#include \"lrs.h\" Action() { int rc,rv;//保存连接成功返回值 char *recvBuf;//保存接收数据的内容 int recvLen;//保存接收数据的大小 /*对于长连接,建立socket连接放在vuser_init函数中,短连接放在Action中即可*/ rc=lrs_create_socket(\"socket0\",\"TCP\",\"RemoteHost=IP:端口\", LrsLastArg); //判断连接是否创建成功 if(rc==0){ lr_output_message(\"Socket连接创建成功\"); } else{ lr_error_message(\"Socket连接创建失败!错误码=%d\",rc); return -1; } lr_start_transaction(\"XXXX_1234_FCX\");//事务开始 //发送socket请求消息(数据包内容放在data.ws中) lrs_send(\"socket0\", \"buf0\", LrsLastArg); //取缓冲区buf0的报文并发送 rv = lrs_receive(\"socket0\", \"buf1\", LrsLastArg);//接收响应报文 if(rv==0){ lr_output_message(\"Socket接收返回消息成功\"); } else{ lr_error_message(\"Socket接收返回消息失败!错误码=%d\",rv); return -1; } //获取最后收到的buffer和大小 lrs_get_last_received_buffer(\"socket0\",&recvBuf,&recvLen); /*设置检查点,验证返回数据是否成功,这个根据各交易具体情况进行判断,以下示例是通过返回报文的长度大于3即为成功*/ if(recvLen>3){ lr_end_transaction(\"XXXX_1234_FCX \",PASS); } else{ lr_end_transaction(\"XXXX_1234_FCX \",FAIL); lr_error_message(\"XXXX_8550_FCX Fail!出错信息:[%s]\", recvBuf);//交易失败时,输出RecvBuf返回信息,用于排查出错原因 } lrs_free_buffer(recvBuf); //释放recvBuf内存空间,否则会引起内存泄露 /*关闭Socket连接,对于长连接,关闭socket连接应放在vuser_end函数中*/ lrs_close_socket(\"socket0\"); return 0; } |
data.ws
1)XML报文格式
;WSRData 2 1 send buf0 360 \"<?xmlversion=\\\"1.0\\\"encoding=\\\"GBK\\\"?>\" \"<TRANINFO>\" \"<HEAD>\" \"<TransCode>S001</TransCode>\" \"<TransDate>20170613</TransDate>\" \"<TransTime>144206</TransTime>\" \"<TransNo>21219603</TransNo>\" \"<Operator>999088</Operator>\" \"<TransInst>70090</TransInst>\" \"</HEAD>\" \"<MSG>\" \"<CustomerID><userID></CustomerID>\"//客户编号 \"<Type>3</Type>\"//查询类型 \"<BusinessType>01</BusinessType>\"//业务类型 \"</MSG>\" \"</TRANINFO>\" recv buf1 300 -1 |
2)16进制报文格式
;WSRData 2 1 send buf0 32 \"\\x00\\x00\\x00\\x1c\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" \" \" \"\\x00\\x00\\x00\\x00\" \"PID <tran>\" recv buf1 197 \"\\x00\\x00\\x00\\x1a\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" \"\\x1e\\x00\\x00\\x00\\x00\" \"STW -1\" \"\\x00\\x00\\x00\\x1e\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" \"\\x1e\\x00\\x00\\x00\\x00\" \"STT \" \"\\x1f\" -1 |
其中buf0代表发送的报文的名称,后跟的数字代码发送报文长度,其下放置发送报文;buf1代表接收报文的名称,后跟数字代表接收报文长度,其下放置接收报文。
注意:该协议脚本参数化格式为:<参数名>