基于TCP的安卓与服务器交互开发
摘要: 安卓系统运用在大量的移动设备当中,而针对安卓与服务器的开发也五花八门。本文使用 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的安卓与服务器交互开发相关推荐
- 基于QT的安卓手机蓝牙APP开发
摘要:前段时间用QT写了一个串口调试助手,感觉还可以.因为QT是跨平台的,同样一套代码可以在windows上面跑,也可以在linux上面跑,也可以在安卓手机上面跑.而且不需要修改任何东西,编译器会自动 ...
- Ai-WB2模组基于TCP的MQTT连接服务器使用示例
前言 1. 准备工作 2. 连接路由器 3. 基于 TCP 的 MQTT 连接(适用于数据量少) 4. 基于 TCP 的 MQTT 连接(适用于数据量多) 5. 联系我们 1. 准备工作 需要准备的软 ...
- 基于Java的音频转发服务器_javaCV开发详解之5:录制音频(录制麦克风)到本地文件/流媒体服务器(基于javax.sound、javaCV-FFMPEG)...
javaCV系列文章: 补充篇: 前言:本篇文章基于javaCV-FFMPEG,关于javaCV官方是没有文档或者api文档可以参考的,所以还有很多地方需要研究: 本章对于ffmpeg的需要有一定了解 ...
- android搭建客户端,用Android搭建客户端 手机和服务器交互开发实例
笔者以前是学的Java EE,由于项目需要要开发Android,所以临时补了一个多星期,主要是手机端和服务器端交互,双向开发的. 首先在服务器端,我采用的是SSH框架,struts 2集合了JSON插 ...
- 基于TCP/UDP的socket服务器搭建流程
目录 TCP/UDP概念介绍 一.TCP/UDP对比 二.端口号的作用 三.字节序 1.概念 2.分类 3.C程序在内存空间的映射 socket服务器与客户端开发流程 一.流程介绍 二.socket服 ...
- strut2服务器与android交互数据,用Android搭建客户端 手机和服务器交互开发
首先在服务器端,采用的是SSH框架,struts 2集合了JSON插件,服务器和客户端的信息交互采用的JSON来传输,由于在服务器端用了Struts 2,所以我就用装了一个JSON插件.这样,很轻易的 ...
- 基于Unity的HTC Vive虚拟现实交互开发(一)环境配置
环境配置 在本篇文章中,我们将重点介绍通过Unity3D来对HTC Vive进行基础的环境配置. 在这个系列的前几篇文章中都是为了之后的开发做准备工作. HTC Vive 进行VR开发的前提是你要有一 ...
- 基于TCP协议的网络程序(基础学习)
下图是基于TCP协议的客户端/服务器程序的一般流程: 图 37.2. TCP协议通讯流程 服务器调用socket().bind().listen()完成初始化后,调用accept()阻塞等待,处于监听 ...
- 基于 TCP协议和sqlite3数据库的网络电子词典(个人项目)
一.开发环境:Ubuntu 16.04 二.项目描述: 基于TCP协议的并发服务器设计,采用sql数据库进行数据存储,文件保存历史查询数据,能满足多用户同时登陆,实现用户的注册.登录以及退出,登录成功 ...
最新文章
- php实现工厂模式,PHP基于工厂模式实现的计算器实例
- 【svn老玩家翻车了,git玩的不够6】git恢复本地误删的文件
- 两个前置摄像头_W21 5G性能篇 | 五摄像头组合,洞悉画面之美
- FFMPEG实现RTSP中H264数据流解码 并且实时播放
- 百度云盘不限速的方法
- 核心指导网络由任务编码器_如何在现实世界中与实际用户一起指导您的编码和编码生涯...
- 计算机组装与维修的前言,计算机组装与维修论文大纲模板 计算机组装与维修论文提纲如何写...
- 最大化 LoRa 长距离,秘籍2:接收灵敏度
- HIVE一些字符处理
- python中head是什么意思_python爬虫中header是什么?怎么用?
- Go 依赖注入库dig
- 如何管理好一个研发管理团队
- 支付宝个人支付接口(蚂蚁金服官方接口)
- git的一套全流程上手(不包括报错(我忘了有哪些报错了)以及其解决方案(篇幅问题))...
- 使用 NodeBB 搭建的中文社区索引
- 【apache lang3】import org.apache.commons.lang3.StringUtils error----Cannot resolve symbol ‘lang3‘
- VUE + Element-ui 按住Shift实现多选
- 取球游戏(C++)[堆]
- 欧拉角中各种角度的名称
- linux下开启、关闭、重启mysql服务命令
热门文章
- buuctf 刷题2(md5(true)参数漏洞php字符串解析特性phpdirsearchphp反序列化)
- Twemproxy – Twitter 开源的 Redis proxy
- 消息队列探秘-RabbitMQ消息队列介绍 侵立删
- 污水处理厂不仅能“喝”啤酒,还能“穿”绿衣,“吃”糖果
- web前端字体居中_css怎样使文字居中?
- CSS定位(position))之sticky 定位
- HTTP_ORIGIN 说明
- 大数据开发工程师基本功修炼之史上最全Linux学习笔记(建议)
- 《她的声音,每一首歌都是一个驿站》_七夕小子_新浪博客
- Games101----Transformation(2)