安卓Socket通信实例
本文摘自:https://whatsblog.icu/index.php/Android/17.html
1、Socket通信必须知道的地方
1、首先,Socket通信采用TCP模式,客户端需要连接到服务端
2、采用网络,需要打开Internet权限
3、需要合理调用线程,熟悉线程与输入输出流的使用
4、socket服务端和客户端编码方式不一致将有可出现中文乱码问题
5、在收发数据前,必须和对方建立可靠的连接。
一个TCP连接必须要经过三次“对话”才能建立,其中的过程非常复杂,过程:主机A向主机B发出连接请求数据包:“我想给你发数据,可以吗?”,这是第一次对话;主机B向主机A发送同意连接和要求同步(同步就是两台主机一个在发送,一个在接收,协调工作)的数据包:“可以,你什么时候发?”,这是第二次对话;主机A再发出一个数据包确认主机B的要求同步:“我现在就发,你接着吧!”,这是第三次对话。三次“对话”的目的是使数据包的发送和接收同步,经过三次“对话”之后,主机A才向主机B正式发送数据。
6、线程:
线程是进程中的一个实体,是被系统独立调度和分配的基本单位。一个进程可以有多个线程,一个线程必须有一个父进程,线程自己不拥有系统资源,只有运行必须的一些数据结构,但它可以与同属一个进程的其他线程共享进程所拥有的全部资源。一个线程可以创建和撤销另一个线程,同一个进程中的多个线程之间可以并发执行。
7、文件输入流与输出流的讲解 :
1、InputStream与OuputStream的区别
:slightly_smiling_face:
不管你从磁盘读,从网络读,或者从键盘读,读到内存,就是InputStream。
不管你写到磁盘,写到网络,或者写到屏幕,都是OuputStream。
Socket通信中也是如此
:apple:
2、如何分清InputStream与OuputStream
我们所说的流,都是针对内存说的,比如为什么打印到屏幕上就是System.out.println();而从屏幕等待用户输入的却是System.in呢?因为对于内存来说,把字符串打印到屏幕上是从内存流向屏幕这个显示器的,也就是输出,而从屏幕等待用户输入呢?就是等待键盘将字符输入到内存中。所以,你根本就不用死记硬背,当你遇到IO的时候,就想两件事,第一,我的内存是中心,第二看看流的方向(矢量)!那我访问网络,看网页是什么呢 网络--------------->内存 是 in 因为我们访问页面是要抓取该页面得一个html文件,那我要是在网络上输入帐号密码登陆呢? 是不是内存的东西要写到该服务器上呢,所以当然是out了!
3、Socket中的Recieve与Send
同样socket编程用到更多的IO,这里分别用Server(服务器端)和Client(客户端)来说明
Server: 遇到请求,网络----->内存 IN 服务器应答, 内存------->网络 OUT-----------------------------------------------------------------Client: 请求服务, 内存----->网络 OUT 服务器应答, 网络------->内存 IN
注:
当服务端需要读取本地ip时可以使用WifiInfo的getIpAddress()方法,服务端部分已集成,可直接初始化调用
2、思路分析:
1、分清Client和Server:
Client即客户端,用于与服务端进行交互,在本实例中用于与服务端一对一聊天。Server即服务端,用于启动服务,供客户端通过指定方式连接(Socket中使用IP地址和端口号)。Server中可以指定端口号,在Client中需要输入服务端的IP地址和端口号才可以进行握手。无论在什么地方的Server总是先运行,Client后运行。Client和Server的初始化方式不一样,出错将导致无法握手!
2、功能模块化
不同的功能使用不同的线程,尽量降低各模块之间的耦合性对于处理类似于控制TextView中的值时,需要专门提供一个线程来处理(Handler的消息机制),避免程序无故报错导致跑飞在线程中需要操作控件时巧妙使用消息传递的中间体:Message,可以完美避免未知错误的产生在 Java 中所有数据都是使用流读写的。流是一组有序的数据序列,将数据从一个地方带到另一个地方。根据数据流向的不同,可以分为输入(Input)流和输出(Output)流两种。在流的使用中必须要使用byte数组!为了保证在握手成功之后正确接收到信息需要在握手过程中传入接收部分功能要懂得在握手断开后处理好异常而不至于报错,同时还可以在程序中直接反馈相关信息,这是最主要的
Manifest联网请求:
举报/反馈