博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(转)JAVA socket 进行十六进制报文交互测试
阅读量:5926 次
发布时间:2019-06-19

本文共 7483 字,大约阅读时间需要 24 分钟。

1 import java.io.IOException;   2 import java.io.InputStream;   3 import java.io.OutputStream;   4 import java.io.PrintWriter;   5 import java.net.ServerSocket;   6 import java.net.Socket;   7    8 public class ServerTest {   9   10     private ServerSocket ss;  11     private Socket socket;  12     PrintWriter out;  13     private int i = 0;  14   15     public ServerTest() {  16         try {  17             ss = new ServerSocket(7838);  18             while (true) {  19                 System.out.println(0);  20                 socket = ss.accept();  21                 ss.setSoTimeout(50000);  22                 byte[] b = new byte[1024];  23                 b[0] = (byte) 0x55;  24                 b[1] = (byte) 0xAA;  25                 b[2] = (byte) 0x01;  26                 b[3] = (byte) 0x00;  27                 b[4] = (byte) 0x00;  28                 b[5] = (byte) 0x00;  29                 b[6] = (byte) 0x00;  30                 b[7] = (byte) 0x00;  31                 b[8] = (byte) 0x00;  32                 b[9] = (byte) 0x00;  33                 b[10] = (byte) 0x00;  34                 b[11] = (byte) 0x00;  35                 b[12] = (byte) 0x00;  36                 b[13] = (byte) 0x00;  37                 b[14] = (byte) 0x00;  38                 b[15] = (byte) 0x00;  39                 b[16] = (byte) 0x00;  40   41                 InputStream socketReader = socket.getInputStream();  42                 OutputStream socketWriter = socket.getOutputStream();  43                 socketWriter.write(b);  44                 System.out.println("OK");  45                 socketWriter.flush();  46                 i = i + 1;  47                 out.flush();  48             }  49         } catch (IOException e) {  50             e.printStackTrace();  51         }  52     }  53   54     public static void main(String[] args) {  55         new ServerTest();  56     }  57 }
上面是我百度的JAVA socket 发送十六进制数据的代码,通过这个思路,我进行了一些抽象:
 
因为我需要模拟多个报文,每个报文都用字节流拆分比较费时间,从网上查询到把一个字符串直接拆分成字节流的方法:
1 public class socketWriter {   2     public static byte[] hexStringToBytes(String hexString) {   3         if (hexString == null || hexString.equals("")) {   4             return null;   5         }   6         // toUpperCase将字符串中的所有字符转换为大写   7         hexString = hexString.toUpperCase();   8         int length = hexString.length() / 2;   9         // toCharArray将此字符串转换为一个新的字符数组。  10         char[] hexChars = hexString.toCharArray();  11         byte[] d = new byte[length];  12         for (int i = 0; i < length; i++) {  13             int pos = i * 2;  14             d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));  15         }  16         return d;  17     }  18     //charToByte返回在指定字符的第一个发生的字符串中的索引,即返回匹配字符  19     private static byte charToByte(char c) {  20         return (byte) "0123456789ABCDEF".indexOf(c);  21     }  22 }

因为我需要对输入流的数据进行解析,所以写了一个公共方法,把字节流转换成字符串:

// 字节的转换  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:8080          socket = 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

 

转载于:https://www.cnblogs.com/tzhyy/p/9232666.html

你可能感兴趣的文章
如何实现自己的SpringBoot自动配置
查看>>
如何免费生成资讯类App
查看>>
Apache Kafka:大数据的实时处理时代
查看>>
三步骤快速开发 iOS资讯类App
查看>>
最强前端性能优化,Google已经为你准备好了
查看>>
java版spring cloud+spring boot+redis多租户社交电子商务平台(十二)断路器监控(Hystrix Dashboard)...
查看>>
阿里云图片上传
查看>>
父传子
查看>>
前端面试题目汇总摘录(HTML 和 CSS篇)
查看>>
异步执行顺序
查看>>
js判断对象是否为空
查看>>
使用jest测试Koa应用
查看>>
开发适用于微信小程序的跨平台图表库:part1
查看>>
亚马逊苹果在中国不行了,下一个该星巴克了?
查看>>
北京—【望京SOHO】样本通 招前端开发工程师(react)
查看>>
Redisson之几种分布式队列
查看>>
可以提高程序员效率的工具!
查看>>
【Swift】类似于微博、微信的ActionSheet
查看>>
b2b b2c o2o分布式电子商务平台源码 Spring MVC+mybatis+spring cloud
查看>>
人工智能会不会变成终结者,这事儿人工智能自己说了不算
查看>>