测试部徐国伟SkyOpenTest之Socket2020/1/311平台:Eclipse、Junit、JDKEclipseEclipse是一个开放源代码的、基于Java的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。Eclipse附带了一个标准的插件集,包括Java开发工具(JavaDevelopmentTools,JDT)。JunitJUnit是一个开放源代码的Java测试框架,用于编写和运行可重复的测试。他是用于单元测试框架体系xUnit的一个实例(用于java语言)。JDKJDK(JavaDevelopmentKit)是SunMicrosystems针对Java开发员的产品。JDK是整个Java的核心,包括了Java运行环境,Java工具和Java基础的类库。工具下载地址:协议:Tcp、HttpTCPTCP是底层(传输层)通讯协议,定义的是数据传输和连接方式的规范,TCP可以对上层协议提供接口,使上层网络数据的传输建立在“无差别”的网络之上。建立起一个TCP连接需要经过“三次握手”,断开一个TCP连接需要经过“四次握手”。HTTPHTTP协议即超文本传送协议(HypertextTransferProtocol),是Web联网的基础,也是手机联网常用的协议之一,定义的是传输数据的内容的规范,HTTP协议是建立在TCP协议之上的一种应用,HTTP协议中的数据是利用TCP协议传输的。2020/1/313公司目前使用的数据格式TCP:1、发送为字节流TLV格式,响应为字节流TLV格式。2、发送数据固定模板格式,响应数据固定模板格式。HTTP:key-value格式、TLV格式1、请求、响应均为字符格式。2、请求为字符KV格式,响应为字节流TLV格式。3、请求为字节流TLV格式,响应为字节流TLV格式。TLV格式TLV为一种可变的数据编码格式,TLV的意思就是:Type(Tag)类型,Length长度(为Value的长度),Value值。其中Type和Length的长度固定,一般都是2、4个字节,Value的长度有Length指定。TLV编码就是指对Type(Tag)、Length和Value进行编码,形成比特流数据包;解码是编码的逆过程,是从比特流缓冲区中解析还原出原始数据。这种格式的优点是:比较灵活、解码方便。2020/1/314Socket介绍Socket套接字(socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示包含进行网络通信必须的五种信息:连接使用的协议(主要分tcpsocket和udpsocket),本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程的协议端口。简单的说就是服务端和客户端通信的一个轨道。ServerSocket我们要创建一个Socket连接,前提必须要有一个连接目标ServerSocket,ServerSocket主要功能是建立服务端端口监听,随时处理来时Client的Socket连接请求。我们平时的测试过程中,ServerSocket信息就是被测服务的ip和监听端口,建立ServerSocket方法如下:ServerSocketserver=newServerSocket(6789);2020/1/315Socket流程Socket流程在了解ServerSocket后我们就可以轻松的建立Socket连接,和服务端进行通信并测试服务端的功能。下图为一个完整的Socket流程:2020/1/316创建Socket打开输出输入流打包sendbuf输出收取recvbuf解包关闭SocketSocket流程代码示例Socket流程代码示例//Socket连接、数据处理和断开连接。publicclassSocketUtil{//建立连接Socketsocket=newSocket(host,port);//打开输出流DataOutputStreamDos=newDataOutputStream(socket.getOutputStream());//打开输入流DataInputStreamDis=newDataInputStream(socket.getInputStream());//发送字节数组流---??Dos.write(SendBuf);//读取服务端返回的字节数组流---?Dis.read(recvbuf);2020/1/317Socket流程代码示例//断言assert-----??//刷新输出流Dos.flush();//关闭输出流Dos.close();//关闭输入流Dis.close();//断开连接socket.close();}2020/1/318Socket测试实例实例项目介绍下面以skyssp(统一短消息服务)项目测试中获取通道接口测试为实例讲解。项目协议文档主要内容:1、消息格式定义-TLV所有消息的组成为TLV(Type-Length-Value)格式,其中Type和Length采用网络字节序的4个字节正整数。2020/1/319Socket测试实例—通用协议约束2、消息组成定义2020/1/3110Socket测试实例—通用协议约束3、消息组成详细定义2020/1/3111SkyOpenTest---ByteUtil数据类型转换方法-ByteUtil2020/1/3112Socket测试实例—请求消息打包//根据以上协议文档内内容打包请求的统一消息格式publicstaticbyte[]reqmsg(byte[]TLVmsg)throwsIOException{//消息头+tlv消息体byte[]ver=ByteUtil.int2bytes(2,1);byte[]transid=ByteUtil.int2bytes((int)(Math.random()*1000000000),16);byte[]msgtype=ByteUtil.int2bytes(1,1);byte[]appid=ByteUtil.int2bytes(321300,3);byte[]tempmsg=ByteUtil.pack(ver,transid,msgtype,appid,TLVmsg);intlen=tempmsg.length+3;byte[]length=ByteUtil.int2bytes(len,3);byte[]msg=ByteUtil.pack(ver,length,transid,msgtype,appid,TLVmsg);returnmsg;}2020/1/3113Socket测试实例—接口定义获取通道接口定义2020/1/3114Socket测试实例—消息Type定义信息类型(Type)定义2020/1/3115Socket实例--TLV消息体打包//获取短信通道号TLV消息体publicstaticbyte[]GetChannelReqTLVmsg(StringmnoType)throwsException{//type--消息类型(获取短信通道号)byte[]type=ByteUtil.int2bytes(1180005,4);//body--运营商类型TLV格式byte[]umnoType=ByteUtil.UTF8string2TLVbytes(18010008,mnoType);//lengthbyte[]length=ByteUtil.int2bytes(umnoType.length,4);//packbyte[]TLVmsg=ByteUtil.pack(type,length,umnoType);returnTLVmsg;}2020/1/3116Socket实例--测试脚本@TestpublicvoidGetChannelTest()throwsException{byte[]GetChannelReqTLV=Pack.GetChannelReqTLVmsg(3);byte[]SendBuf=Pack.reqmsg(GetChannelReqTLV);Dos.write(SendBuf);Thread.sleep(1000);byte[]recvbuf=newbyte[1024];Dis.read(recvbuf);intrespcode=ByteUtil.getTLVInt(recvbuf,18010001);StringchNumber=ByteUtil.getTLVString(recvbuf,18010009);System.out.println(返回状态码:+respcode);System.out.println(短信通道号:+chNumber);}2020/1/3117Socket实例--测试脚本publicclassGetChannelReq{//定义全局变量Socketsocket;DataOutputStreamDos;DataInputStreamDis;@Before//建立Socket连接并打开输入输出流,并进行通行证验证publicvoidSetup()throwsException{socket=newSocket(172.16.4.171,10007);Dos=newDataOutputStream(socket.getOutputStream());Dis=newDataInputStream(socket.getInputStream());byte[]SendBuf=Pack.MoRegisterReqMsg(160,d112e8io%$)mLKJYYo);Dos.write(SendBuf);byte[]recvbuf=newbyte[1024];Dis.read(recvbuf);}@After//断开连接publicvoidTearDown()throwsException{Dos.flush();Dos.close();Dis.close();socket.close();}@Test//测试执行}2020/1/3118Socket练习Skyssp发送下行短信接口2020/1/3119Socket--练习信息类型(Type)定义2020/1/3120Socket--练习练习步骤1、理解接口说明,根据接口说明和type定义表准备发送请求的TLV格式数据包。短信内容自己随便写,目标手机号填写自己的号码。2、确认手机有没收到短信。3、思考:确认数据库中有没短信记录?2020/1/31212020/1/3122谢谢!