JAVA socket 进行十六进制报文交互测试
来源:互联网 发布:客户资料整理软件 编辑:程序博客网 时间:2024/05/01 07:45
import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.io.PrintWriter;import java.net.ServerSocket;import java.net.Socket;public class ServerTest {private ServerSocket ss;private Socket socket;PrintWriter out;private int i = 0;public ServerTest() {try {ss = new ServerSocket(7838);while (true) {System.out.println(0);socket = ss.accept();ss.setSoTimeout(50000);byte[] b = new byte[1024];b[0] = (byte) 0x55;b[1] = (byte) 0xAA;b[2] = (byte) 0x01;b[3] = (byte) 0x00;b[4] = (byte) 0x00;b[5] = (byte) 0x00;b[6] = (byte) 0x00;b[7] = (byte) 0x00;b[8] = (byte) 0x00;b[9] = (byte) 0x00;b[10] = (byte) 0x00;b[11] = (byte) 0x00;b[12] = (byte) 0x00;b[13] = (byte) 0x00;b[14] = (byte) 0x00;b[15] = (byte) 0x00;b[16] = (byte) 0x00;InputStream socketReader = socket.getInputStream();OutputStream socketWriter = socket.getOutputStream();socketWriter.write(b);System.out.println("OK");socketWriter.flush();i = i + 1;out.flush();}} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args) {new ServerTest();}}
上面是我百度的JAVA socket 发送十六进制数据的代码,通过这个思路,我进行了一些抽象:
因为我需要模拟多个报文,每个报文都用字节流拆分比较费时间,从网上查询到把一个字符串直接拆分成字节流的方法:
public class socketWriter {public static byte[] hexStringToBytes(String hexString) {if (hexString == null || hexString.equals("")) {return null;}// toUpperCase将字符串中的所有字符转换为大写hexString = hexString.toUpperCase();int length = hexString.length() / 2;// toCharArray将此字符串转换为一个新的字符数组。char[] hexChars = hexString.toCharArray();byte[] d = new byte[length];for (int i = 0; i < length; i++) {int pos = i * 2;d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));}return d;} //charToByte返回在指定字符的第一个发生的字符串中的索引,即返回匹配字符private static byte charToByte(char c) {return (byte) "0123456789ABCDEF".indexOf(c);}
}
因为我需要对输入流的数据进行解析,所以写了一个公共方法,把字节流转换成字符串:
// 字节的转换public class ByteUtil { //将字节数组转换为short类型,即统计字符串长度public static short bytes2Short2(byte[] b) {short i = (short) (((b[1] & 0xff) << 8) | b[0] & 0xff);return i;}//将字节数组转换为16进制字符串public static String BinaryToHexString(byte[] bytes) {String hexStr = "0123456789ABCDEF";String result = "";String hex = "";for (byte b : bytes) {hex = String.valueOf(hexStr.charAt((b & 0xF0) >> 4));hex += String.valueOf(hexStr.charAt(b & 0x0F));result += hex + " ";}return result;}}
import java.net.Socket;import Base.ByteUtil;import Base.socketWriter;import java.io.InputStream;import java.io.OutputStream;public class ClientLaunch {// 这个客户端连接到地址为xxx.xxx.xxx.xxx的服务器,端口为10020,并发送16进制到服务器,然后接受服务器的返回信息,最后结束会话。// 客户端,使用Socket对网络上某一个服务器的某一个端口发出连接请求,一旦连接成功,打开会话;会话完成后,关闭Socket。客户端不需要指定打开的端口,通常临时的、动态的分配一个1024以上的端口。public String Client(Socket socket, socketWriter s, InputStream socketReader, String strInput) {String strOutput = "";try {//客户端输出流作为服务器的输入OutputStream socketWriter = socket.getOutputStream();socketWriter.write(s.hexStringToBytes(strInput));socketWriter.flush();Thread.sleep(1000);//服务器的输出即为客户端的输入,这里主要是为了把服务器输出的字节流报文转化成字符串,方便进行解析,最终测试报文的正确性socketReader = socket.getInputStream();//因为我测试的报文包含报文头和报文体,这里的字节数组长度37为报文头长度byte[] temp = new byte[37];int bytes = 0;/* read从输入流socketReader中读取temp(37)数量的字节数,并将它们存储到缓冲区数组temp。实际读取的字节数作为一个整数37返回。 * 此方法块,直到输入数据可用,检测到文件结束,或抛出异常。如果B的长度为零,则没有读取字节数和返回0; * 否则,将有一个至少一个字节的尝试。如果没有可用的字节,因为流是在文件的结尾,值- 1返回;否则,至少一个字节被读取和存储到temp。*/bytes = socketReader.read(temp);if (bytes != 37) {return null;}strOutput += ByteUtil.BinaryToHexString(temp);//读取报文体的内容byte[] array = new byte[2];for (int i = 1; i < 3; i++) {array[i - 1] = temp[i];}int let = ByteUtil.bytes2Short2(array);array = new byte[let];bytes = socketReader.read(array);if (bytes != let) {return null;}strOutput += ByteUtil.BinaryToHexString(array);//把字符串中“ ”去掉strOutput = strOutput.replaceAll(" ", "");} catch (Exception e) {e.printStackTrace();}return strOutput;}}
这样就完成了报文数据传送,以及读取的基础代码,调用它们即可完成交互,如测试报文数据的处理:
public class CardFlow {ClientLaunch cl = new ClientLaunch();Socket socket;socketWriter socketWriter = new socketWriter();InputStream socketReader; @Test public void cardFlow() throws Exception {// 建立 socket链接,连接服务器192.168.1.1:8080socket = new Socket("192.168.1.1", "8080");String charger="00000000136";//登陆,通过验证输出报文中的响应报文是否为 "000000",判断是否登陆成功,其中loginInput为输出报文字符串String loginInput="283400120001"+charger+"10002016112214151800000000321321233212FFFFFFFFFFFFFFFF00010201";String outlogin = cl.Client(socket, socketWriter, socketReader, loginInput);Assert.assertEquals(outlogin.substring(30,36), "000000");//心跳,通过验证输出报文中的响应报文是否为 "000000",判断是否交互成功String heartbeatInput="283400130001"+charger+"1000201611221415180000";String outheartbeat = cl.Client(socket, socketWriter, socketReader, heartbeatInput);Assert.assertEquals(outheartbeat.substring(30,36), "000000");socket.close(); }}
则完成socket报文交互测试的实现流程:
1. 读取协议配置
2. 替换可变长度和值
3. 计算包体长度
4. 包头+包长度+包体+包尾
5. 建立到192.168.1.1:8080的 socket连接
6. 发送数据包
7. 等待接收返回数据包(超时)
8. 解析返回数据包
9. 得到定位值1和定位值2(便于验证)
该方法完成后,可以进行基于协议的压力测试:
针对频繁请求和处理的协议(不频繁默认无问题),自动生成多测试数据,多客户端多线程长时间进行协议测试,不断加压,统计请求响应时间变化、失败和成功的数据及比例,并收集服务器性能参数和资源消耗等数据(可自动出图),手动检查和数据结果分析。
附:通用自动化测试工具效果
1. 主体框架实现特定功能,高级语言完成,并开放大量实用API,且不断增加和完善
2. 嵌套或封装一种或多种脚本语言解析器,能够动态执行测试用例脚本,对Windows窗体、Web、代码、接口、协议或性能等若干方面进行测试(扩展:录制功能)
3. 流程完善,能够准确高效的解放人力和深入测试,手工尽可能少的参与或专注于测试用例脚本工作
4. 可扩展性强,能够远程操控多个多种平台(分布集群,通过网络通信、协议通信等),能够并行调度执行,可配置可存储,资源共享方便
5. 自动化框架工作:检测新的版本-->下载、编译、批量部署-->调用指定测试脚本执行测试-->邮件或消息通知QA测试结果报告路径和发现的bug。
6. 手工工作:编写修改测试脚本并上传、收邮件校验bug。
1 0
- JAVA socket 进行十六进制报文交互测试
- java socket报文通信
- java socket报文通信-报文的封装
- Loadrunner中socket协议十六进制报文参数化方法
- socket连接 java服务器端 C#客户端进行交互 简单例子
- java NIO Socket交互
- java socket报文通信(二)报文的封装
- java socket报文通信(二)报文的封装
- java socket报文通信(二)报文的封装
- java socket报文通信(二)报文的封装
- java socket报文通信(二)报文的封装
- java socket报文通信(二)报文的封装
- Loadrunner11以Java Vuser进行socket压力测试
- java 网络流 TCP Socket和SeverSocket 互相交互对字符串进行大写转换
- Java socket报文通信(一)socket的建立
- java socket报文通信(一) socket的建立
- Java socket报文通信(一)socket的建立
- Java socket报文通信(一)socket的建立
- EasyUI自定义验证-ajax验证用户名是否可用,成功并跳转页面
- SQL 内按位与运算 &
- Android内存泄漏(笔记)
- 如何评价 GitHub 发布的文本编辑器 Atom?
- jQuery异步提交form表单
- JAVA socket 进行十六进制报文交互测试
- ubuntu环境安装php7+ngnix+mysql
- linux下创建mysql用户
- Java中的反射和类装载器
- 命令行运行Unity脚本
- libCEF总结02字符串
- set命令简介
- EditText末尾添加删除小圆圈一键清空
- 薪酬模块生成工资条