最近公司的产品用到了socket通信方面的东西,花了点时间学习了下,基本使用什么的网上很容易找,就不说啦,这里呢,我把我遇到的坑们给大家唠唠,希望对大家有所帮助。
(○’ω’○)
1. android网络请求需要放在工作线程中,socket通信也不例外;
2. 当socket长连接建立成功后,如果手机屏幕关闭,只要过很短的时间,android系统就会将socket服务挂起,这种行为应该是出于节电考虑的,但体验会下去很多,因为总是自动断开!另外当我们的手机通过数据线连接电脑调试的时候,手机熄灭屏幕后,socket服务是不会被自动挂起的,似乎在调试模式下,手机不会自动进入节电模式,但当连接数据线充电的的话,手机在熄屏后还是会将socket服务挂起的ㄟ( ▔, ▔ )ㄏ。如果希望手机在熄屏后不将socket服务挂起,可以通过PowerManager设置电源模式,使cpu不进入节电模式,当然了,可以做个计时器,也别让cpu全马力输出太久嘛。
3. 客户端希望确认服务器端是否在运行,可以发送心跳包;
4. 如果客户端和服务器端需要双向确认对方是否存活,可以自定义一个易区分的字段,时时发送,在网络畅通的前提下,发送端如果发送失败,则接收端停止运行,接收端如果超过某个时间段之后依然无法接收到信息,则发送端停止运行;
5. socket通信,在发送数据时如果发送的数据被转化为byte后,长度超过1448时,发送的数据将被拆分,比方说,发送一个1500长数据,就会接收到2个包,包内携带的发送信息的长度分别为1448和52;
6. 为了解决socket的这种自动拆包问题,我们需要在发送的信息中写入所发送的信息的总长度,比如,首先我们可以将发送的第一位设置为“$”,它就表示数据的开头,接下来后四位用来存放数据的总长度,之后的部分用来存放发送数据,这样,接收端在接收到数据后就可以通过解析出数据的总长度来确认是否已经接收完全,如果不全再继续接收就可以了;
7. 发送数据过长时会有自动拆包的问题,当发送数据过短或者发送的数据之间时间间隔很短的时候,还会发生自动粘包的问题!自动粘包就是指本来是两个或者多个包中的数据同时合并到了一个包中,这时候,容易出现解析不全的情况。解决粘包问题同样可以使用上面提到的方法,只不过反过来了,当发现接收到的数据比通过首部一至五位计算出的长度要长时,可以通过截取的方法,分段计算;
8. 别以为自动拆包和自动粘包是互斥的,它们也有可能同时出现! (╯‵□′)╯︵┻━┻ 首先发生粘包,而粘包的长度超过了1448,然后就会发生拆包。。。处理方法也不难,接收端首先处理粘包,当处理到最后一个包时会发现最后一个包不完整,将他保存下来,与接下来接收到的数据进行拼接,然后接续处理粘包就可以了,调用流程就是:处理粘包、处理拆包、处理粘包。。。就可以了。
9. socket在api19之前没有继承Closeable接口,如果大家是通过写一个关闭Closeable对象的工具类来关闭socket的话还是别用了,不然老版本的手机们只要一执行到关闭socket的语句时就会异常退出;
10. socket在通信的时候可能需要启动多个线程,可以考虑使用线程池,线程池操作多个线程到底是方便些,而且因线程长时间持有socket对象而产生内存溢出的情况会少很多,因为线程池可以集体关闭所有线程;
11. 在熄屏的情况下,安卓端是接收不到UDP广播的,试过各种方法,就是接收不到。查了下,发现是安卓本身的机制,没发现啥解决方案。
先写这么多吧
(,,• ₃ •,,)(,,• ₃ •,,)