摘要: 安卓系统运用在大量的移动设备当中,而针对安卓与服务器的开发也五花八门。本文使用 TCP 协议传输数据,对安卓设备与服务器之间的交互方式进行了探究与开发。实现了指南针、表达式求值、远程画板几个子功能。

关键词: TCP、安卓开发、服务器

开发目的

​ 移动设备与服务器的互联已经广泛的运用在了我们的生活中。本文拟通过无线连接并采用 TCP 传输协议进行移动设备与服务器的通讯。

一、实验设备

  • 安卓手机一部:Google Pixel 2 XL,安卓版本 9
  • 带热点功能的笔记本电脑一台,充当服务器
  • 开发环境:Android Studio,JetBrains IDEA 及抓包软件 WireShark

二、实验准备及环境配置

​ 配置相应的 Java 环境、AS 的环境。在手机上打开开发者模式并允许 USB 调试。电脑打开热点(本地连接 1),手机连接对应的 WIFI,确保二者处于同一网络中。

​ 本次实验中,服务器 IP 为 192.168.137.1。手机的 IP 随机分配。

三、设计思路

3.1 手机客户端架构

​ MainActivity 类显示各个功能模块,以及发出指令。

​ TaskCenter 是一个单例的类,包装了建立连接、发送以及接收的功能。在 TCP 连接的时候,会创建一个用于连接的线程。TCP 发送的时候,也需要建立一个线程,并在线程中加入接收数据的方法。

​ 每当需要向服务器发送数据的时候,主线程会调用 TaskCenter 单例的 send 函数发送数据。每当收到数据的时候,TaskCenter 会通知主线程(通过回调函数)进行相应的处理。

​ 在建立连接的时候,需要创建一个套接字,指定服务器 IP 以及端口号。

3.2 电脑服务器端架构

​ 服务器运行的时候,会创建套接字并监听相应的端口。为了提高运行的效率,当抓到包时,会创建一个新的线程,处理相应的数据。而主线程则继续监听端口。

​ 其中,传回给客户端的指南针数据由加速度与地磁强度综合得到,表达式求值结果有求值函数计算并回传到客户端。而得到的触摸屏数据不回传,而是经过处理之后在本地绘图。

3.3 收发包的实现

​ 创建了 TCP 套接字后,通过 socket.getInputStream 可以得到 TCP 报文的 padding(附加数据)内容。于是,使用一个 BufferReader 对象保存输入的内容,每次调用 bufferreader.nextLine 方法就可以得到收到的数据。但是,使用 bufferreader,nextLine 方法时,必须保证传输的报文以换行符结束,不然无法读到尽头。

​ 使用一个 PrintWriter 或者一个 BufferWriter 对象保存 socket.getOutputStream,可以进行自动发包。每次在输出流中输出 byte 类型的数组,再调用 flush 方法即可发送 TCP 报文。

​ 这样做可以收发包的原理我没有深究,按照我的理解,在创建套接字的时候,系统会为该套接字开辟一块输入和输出的缓冲区。当有 TCP 报文来时,会过滤掉包头,把包的数据内容放入输入缓冲区,而 BufferReader 的对象相当于一个指针,指向的内容由 socket.getInputStream 获得,每次能够从缓冲区中读一行。写入的 byte 数组会写到输出缓冲区中,而输出缓冲区的地址由 socket.getOutputStream 给出,调用 flush 方法表示清空缓冲区,也就是唤醒操作系统发包。

类型 符号 数据
加速度 ACCELEROMETER 三个浮点数,分别表示 xyz 轴的加速度
地磁强度 MAGNETIC 三个浮点数,分别表示 xyz 轴的磁场强度
触摸感应 TOUCH,DOWN 两个浮点数,表示触摸开始的坐标
触摸感应 TOUCH,MOVE 两个浮点数,表示触摸的实时的坐标
触摸感应 TOUCH,UP 两个浮点数,表示触摸结束时的坐标
表达式 EXPRESSION 一个字符串,表示一个表达式

​ 由于不同的数据类型均通过 TCP 协议传输,所以还需要规定数据区域的格式:以逗号分隔,前半部分为数据类型,后半部分为数据内容。

四、功能实现

4.1 连接与接收功能的实现

​ 对于客户端,连接功能需要新建一个线程。创建一个 Socket 对象,指定 IP 和端口,此时即自动连接。当服务器处于开启状态的时候,socket.isConnected()方法返回 true,表示成功连接。这个时候,分别用 BufferReader 和 BufferWriter 对象保存 socket.getInputStream 和 socket.getOutputStream。然后跳转到 receive() 方法,准备接受服务器传过来的内容。只要 socket.isConnected()返回值为真,就需要一直不停地获取收到的TCP 数据。

​ 当 BufferWriter 对象收到数据的时候(这个方法应该是阻塞的),调用回调函数(callback),并传入报文,通知 main 中的相应的函数,对回调的内容做出及时的反应。

​ 对于服务器,首先创建一个 socket 服务器对象 ServerSocket。然后在一个循环中,创建 socket,其值为 serversocket.accept()的返回值,表示接收套接字。然后开启新的线程获取收到的数据,根据类型选择相应的处理函数。对于指南针功能,需要计算转角,所以需要确保分别收到了线性加速度数据和地磁强度的数据。对于触摸屏的数据,需要在电脑的 Java 图形框中绘制出同样的图形,所以得保证从收到 TOUCH,DOWN 开始的两份数据。处理完后,回传给客户端即可。

4.2 指南针功能的实现

​ 得到加速度和地磁强度后,需要调用 getRotationMatrix 以及 getOrientation 两个方法计算转角。在客户端中,设置了一个设备监听器的频率 SensorManager.SENSOR_DELAY_NORMAL,每隔这样一段时间就要发送TCP 报文。

4.3 表达式求值功能的实现

​ 中缀转后缀,具体实现略。客户端中表达式求值的报文通过点击按钮手动发出。

4.4 绘图功能的实现

​ 在 JFrame 框架下,使用 Graphics2D 对象进行绘图,连续触摸时,由于两个点之间的具体很短,所以使用直线工具进行绘图,使用上一个触点的坐标和现在触点的坐标。在客户端中,每当触摸到画板的时候,发送 TCP 报文。

五、使用手册及运行结果


​ 初始的时候,不会显示触点坐标,当在下方绘制图形的时候,会显示触摸点的坐标。中间接收栏中的内容为指南针需要转过的角度。指南针在屏幕的左上方。

​ 下面是服务器上绘制出来的图形

​ 对于计算表达式的功能,需要在 send 按钮旁边的文本框中填入相应的表达式,并点击 send 传给服务器,服务器计算完毕后再传回客户端,在下面显示。

​ 这些过程中,抓包结果如下:

​ 可以从抓包结果中看到传输类型,收发方 IP 以及运行端口还有数据段内容。

六、总结

这个小 APP 的开发并未实现什么具体功能,而是简单揉合了几个功能,其目的主要是加深对客户端、服务器之间传输方式的理解。

由于是第一次写 Android 的 APP,难免会有很多 BUG 以及代码架构上的不足之处。

References:

  • Android TCP 客户端的实现 https://www.jianshu.com/p/d8fe6e3fc00b

  • 传感器之方向:使用加速度传感器和地磁传感器共同实现 https://blog.csdn.net/An_nAl/article/details/78902572

  • android 中 getOrientation 是如何求得对应的航向角、俯仰角以及翻滚角的? https://www.zhihu.com/question/33565613

  • http://www.biyezuopin.vip

  • SensorManager.getRotationMatrix 函数原理解释 https://www.cnblogs.com/zuoxiaofei/p/4244238.html

  • Android 获取点击屏幕的位置坐标 https://blog.csdn.net/carter_yu/article/details/50499040

基于TCP的安卓与服务器交互开发相关推荐

  1. 基于QT的安卓手机蓝牙APP开发

    摘要:前段时间用QT写了一个串口调试助手,感觉还可以.因为QT是跨平台的,同样一套代码可以在windows上面跑,也可以在linux上面跑,也可以在安卓手机上面跑.而且不需要修改任何东西,编译器会自动 ...

  2. Ai-WB2模组基于TCP的MQTT连接服务器使用示例

    前言 1. 准备工作 2. 连接路由器 3. 基于 TCP 的 MQTT 连接(适用于数据量少) 4. 基于 TCP 的 MQTT 连接(适用于数据量多) 5. 联系我们 1. 准备工作 需要准备的软 ...

  3. 基于Java的音频转发服务器_javaCV开发详解之5:录制音频(录制麦克风)到本地文件/流媒体服务器(基于javax.sound、javaCV-FFMPEG)...

    javaCV系列文章: 补充篇: 前言:本篇文章基于javaCV-FFMPEG,关于javaCV官方是没有文档或者api文档可以参考的,所以还有很多地方需要研究: 本章对于ffmpeg的需要有一定了解 ...

  4. android搭建客户端,用Android搭建客户端 手机和服务器交互开发实例

    笔者以前是学的Java EE,由于项目需要要开发Android,所以临时补了一个多星期,主要是手机端和服务器端交互,双向开发的. 首先在服务器端,我采用的是SSH框架,struts 2集合了JSON插 ...

  5. 基于TCP/UDP的socket服务器搭建流程

    目录 TCP/UDP概念介绍 一.TCP/UDP对比 二.端口号的作用 三.字节序 1.概念 2.分类 3.C程序在内存空间的映射 socket服务器与客户端开发流程 一.流程介绍 二.socket服 ...

  6. strut2服务器与android交互数据,用Android搭建客户端 手机和服务器交互开发

    首先在服务器端,采用的是SSH框架,struts 2集合了JSON插件,服务器和客户端的信息交互采用的JSON来传输,由于在服务器端用了Struts 2,所以我就用装了一个JSON插件.这样,很轻易的 ...

  7. 基于Unity的HTC Vive虚拟现实交互开发(一)环境配置

    环境配置 在本篇文章中,我们将重点介绍通过Unity3D来对HTC Vive进行基础的环境配置. 在这个系列的前几篇文章中都是为了之后的开发做准备工作. HTC Vive 进行VR开发的前提是你要有一 ...

  8. 基于TCP协议的网络程序(基础学习)

    下图是基于TCP协议的客户端/服务器程序的一般流程: 图 37.2. TCP协议通讯流程 服务器调用socket().bind().listen()完成初始化后,调用accept()阻塞等待,处于监听 ...

  9. 基于 TCP协议和sqlite3数据库的网络电子词典(个人项目)

    一.开发环境:Ubuntu 16.04 二.项目描述: 基于TCP协议的并发服务器设计,采用sql数据库进行数据存储,文件保存历史查询数据,能满足多用户同时登陆,实现用户的注册.登录以及退出,登录成功 ...

最新文章

  1. php实现工厂模式,PHP基于工厂模式实现的计算器实例
  2. 【svn老玩家翻车了,git玩的不够6】git恢复本地误删的文件
  3. 两个前置摄像头_W21 5G性能篇 | 五摄像头组合,洞悉画面之美
  4. FFMPEG实现RTSP中H264数据流解码 并且实时播放
  5. 百度云盘不限速的方法
  6. 核心指导网络由任务编码器_如何在现实世界中与实际用户一起指导您的编码和编码生涯...
  7. 计算机组装与维修的前言,计算机组装与维修论文大纲模板 计算机组装与维修论文提纲如何写...
  8. 最大化 LoRa 长距离,秘籍2:接收灵敏度
  9. HIVE一些字符处理
  10. python中head是什么意思_python爬虫中header是什么?怎么用?
  11. Go 依赖注入库dig
  12. 如何管理好一个研发管理团队
  13. 支付宝个人支付接口(蚂蚁金服官方接口)
  14. git的一套全流程上手(不包括报错(我忘了有哪些报错了)以及其解决方案(篇幅问题))...
  15. 使用 NodeBB 搭建的中文社区索引
  16. 【apache lang3】import org.apache.commons.lang3.StringUtils error----Cannot resolve symbol ‘lang3‘
  17. VUE + Element-ui 按住Shift实现多选
  18. 取球游戏(C++)[堆]
  19. 欧拉角中各种角度的名称
  20. linux下开启、关闭、重启mysql服务命令

热门文章

  1. buuctf 刷题2(md5(true)参数漏洞php字符串解析特性phpdirsearchphp反序列化)
  2. Twemproxy – Twitter 开源的 Redis proxy
  3. 消息队列探秘-RabbitMQ消息队列介绍 侵立删
  4. 污水处理厂不仅能“喝”啤酒,还能“穿”绿衣,“吃”糖果
  5. web前端字体居中_css怎样使文字居中?
  6. CSS定位(position))之sticky 定位
  7. HTTP_ORIGIN 说明
  8. 大数据开发工程师基本功修炼之史上最全Linux学习笔记(建议)
  9. 《她的声音,每一首歌都是一个驿站》_七夕小子_新浪博客
  10. Games101----Transformation(2)