基于TCP协议的Android模拟器间通信在教学中的应用研究
2018-12-20许姗姗
许姗姗
(厦门软件职业技术学院,福建厦门 361000)
1 研究背景
随着科技的迅速发展,移动网络以及智能手机的普及让人们的生活发生了巨大的变化。Android网络开发就是实现不同终端之间的通信,其中一个应用就是把复杂的数据操作运算放在计算机终端,来实现手机的高功能运行[1]。
目前,基于TCP/IP协议的Socket通信是广泛应用的通信协议之一。基于TCP/IP协议的Socket通信,是通过指定IP地址和port号,采用c/s模式建立TCP协议下的两个通信进程间的连接,实现可靠的双向通信[2]。生活中越来越多的厂商会将物联网技术与智能硬件组合在同一个局域网内,由网关通过指令统一控制智能硬件。例如,火焰报警信息传递、监控点的智能相机等平台,就是采用高实时性的基于TCP协议的Socket通讯技术,将传感器数据实时送达。人们平常使用的网络聊天程序、迅雷下载程序等都需要用到Socket通信技术。
国内外对于Socket的研究主要包括基于TCP/IP协议关于Socket通信程序的研究、Sokcet的网络编程研究与实现等,现在已取得了较为成熟的成果[3]。但在教学中经常遇到了以下的问题:在使用Android studio开发环境下,开发两个APP,如果将它们各自部署到运用Android系统的手机上,在同一个Wi-Fi下是可以成功通信的。但在课堂上这样操作会比较麻烦,通常学生很少携带两部手机。如果能快速地将这两个APP发布到同一台电脑的不同Android模拟器上进行通信,则会既简单又高效,这是本文研究的主要思路。
2 基于TCP协议的Socket通信机制
TCP/IP协议为传输控制协议/因特网互联协议,是Internet最基本的协议,也是Internet国际互联网络的基础,由网络层的IP协议和传输层的TCP协议组成[4]。Socket定义了一些规范,我们只需要遵循Socket的规定去编程即可。
Socket是应用层与TCP/IP协议簇通讯的中间抽象层,Socket是一组接口,通常被称作“套接字”[5]。简单来说,Socket提供了程序内部与外界通信的端口,并为通信双方提供了数据传输通道[6]。基于Sokcet的网络编程的主要操作流程如下:
2.1 套接字服务端的具体流程
(1)调用类ServerSocket的ServerSocket(int aport)方法创建一个ServerSocket对象,并绑定到指定端口。(2)调用accept()方法,监听连接请求,如果客户端请求连接,则接受连接,并返回一个Socket对象。(3)通过Socket对象的getInputStream()和Socket对象的getOutputStream()方法获得输出流和输入流,程序开始进入数据的接收和发送[7]。(4)关闭流、ServerSocket对象及Socket对象。
2.2 套接字客户端的具体流程
(1)调用Socket(InetAddress dstAddress,int dstPort)创建一个Socket对象,并连接到服务器端。(2)通过Socket对象.getInputStream()和Socket对象.getOutputStream()方法获得输出流和输入流,开始进入数据的接收和发送。(3)关闭流和Socket对象。
套接字客户端与服务端通信的具体流程图如1所示。
图1 套接字客户端与服务端通信的流程图
3 模拟器间通信需要解决的问题
计算机之间可以通过IP地址进行通信,IP地址都是唯一的。Android模拟器提供了一个特殊的IP地址10.0.2.2,如果同一台计算机开启了两个Android模拟器,那这两个模拟器的IP是一样的,都是10.0.2.2。而IP相同的两台模拟器间如何通信是我们需要解决的问题。经过研究,通过端口重定向技术,可实现Android模拟器之间的通信。端口重定向技术的具体操作如下:
(1)先在“我的电脑”右键属性,进入“高级系统设置”,选择“高级”选项卡,进入“环境变量”,选择系统变量名Path,将SDK中platform-tools所在的路径复制粘贴进去。如图2所示。
图2 在系统变量Path中添加SDK的platform-tools所在路径
(2)启动两个Android Studio自带的模拟器,假设一个为emulator-5554,另一个为emulator-5556。将emulator-5554设定为服务器,将emulator-5556设定为客户端。Android的模拟器有个特点,就是程序访问网络的时候只可以从模拟器连接到外界,但是却无法从外界连接模拟器。用户想要从外界连接上模拟器,需要将端口重定向[8]。首先在cmd中执行命令Telnet localhost 5554,远程登录服务器,如果提示该命令无效,则要进入控制面板,单击“程序和功能”类别,打开“Windows功能”对话框,勾选“Telnet客户端”组件,具体操作如图3所示。
图3 打开Telnet客户端
接着重新执行命令Telnet localhost 5554,命令行窗体提示“正在连接localhost...”,这样就可以远程登录服务器,出现一个标题为“Telnet localhost”的窗体,如图4所示。
图4 远程登录服务器
接下来输入命令“help”,查看列表中是否有“redir”命令,如果没有,则必须进行身份认证,方法很简单,只需通过上面窗体中的“C∶UsersAdministrator。emulator_console_auth_token”这串路径找到对应文件,复制文件中的字符串,通过命令“auth字符串”,就能通过认证,如图5所示。
图5 通过命令“auth字符串”进行身份证
最后再次输入命令“help”,就能在列表中看到“redir”命令。输入命令“redir add tcp∶1112∶1111”,即可完成端口重定向,如图6所示。其中,1112是客户端new Socket(“10.0.2.2”,1112)的端口,1111是服务端new ServerSocket(“1111”)的端口。完成这步端口重定向后,外界也可以连接上模拟器,即模拟器emulator-5556可以连接上emulator-5554了。
图6 使用“redir”命令进行端口重定向
4 模拟器间通信的具体应用
创建两个Android应用程序:一个作为服务端程序;一个作为客户端程序。
(1)服务端程序关键代码如下:
serverSocket=new ServerSocket(1111);//绑定到指定端口
Log.i("ServerActivity","服务器启动了");
socket=serverSocket.accept();//等待Socket请求,直到连接被打开。
Log.i("ServerActivity","有客户连接到服务器");
服务端绑定到指定的端口为1111,当用户点击按钮、启动服务端后,程序执行ServerSocket对象的accept()方法,监听连接请求,如果客户端请求连接,则服务端接受连接,并返回一个Socket对象。建立连接后程序通过socket.getOutputStream()和socket.getInputStream()进行数据的传输。
(2)客户端程序关键代码如下:
socket=new Socket("10.0.2.2",1112);//以本机另一个模拟器为服务端,则IP地址是10.0.2.2。
客户端绑定到指定的端口为1112,连接到本地的模拟器的IP为10.0.2.2。当用户点击按钮,客户端连接上服务器后,程序就可以通过socket.getOutputStream()和socket.getInputStream()进行数据的传输。
这里需要将模拟器的端口进行重定向,使用命令“redir add tcp∶1112∶1111”,具体用法上文有详细说明。运行程序,将服务端程序运行在模拟器emulator-5554上,将客户端程序运行在模拟器emulator-5556上。点击服务端界面的“启动服务端程序”按钮,客户端界面会显示“服务端:我已经启动了”字样,点击客户端界面的“连接服务端程序”按钮,服务端界面会显示“客户端:我已连接上你了”字样,这时表明服务端和客户端已连接成功,可以进行通信了。运行效果如图7和图8所示。
图7 服务端界面
图8 客户端界面
5 结语
本文运用端口重定向技术实现了同一台计算机上两个Android模拟器间的通信,通过端口重定向技术使外界也能连接上模拟器。在教学中可以直接将应用程序部署到模拟器上进行网络通信,解决了课堂上没有太多真机可用于测试的问题,同时还可以应用于初创企业。目前运用Android系统的手机机型众多,系统版本多,保证应用程序的兼容性是在应用上架前必做的测试之一。而兼容性测试对于网络开发的初创企业而言是一大难题,可使用本文提出的模拟器间通信的方法先进行通信测试,再到一些网站上进行兼容性测试(例如,WeTest平台就提供了移动端测试服务)。