处于通用性考虑,对原先的socket进行了去安卓化
原有实现:
服务器端句柄获取:
android_get_control_socket(SOCKET_NAME)
客户端句柄获取:
fd = socket_local_client(SOCKET_NAME,
ANDROID_SOCKET_NAMESPACE_RESERVED,
SOCK_STREAM );
init.rc里实现如下:
socket SOCKET_NAME stream 660 root radio
客户端由系统其他模块启动
******************************************************************************************************************************************************************************************************
修改后
全部采用通用化做法
服务器端:socket -> bind -> listen -> select -> accetp
客户端:socket -> connect
这回客户端启动方式修改为自启动
客户端进程在rc中采用service的形式,如下
service SOCKET_CLIENT_SERVICE system/bin/socket_client_service
user XXX
oneshot
class main
运行之后,客户端大概率报 connection refused
第一怀疑就是会不会是客户端进程权限不够。于是手动kill客户端进程,并手动敲命令启动,发现这回可以启动。
于是将客户端对应的service的user XXX直接去除,这样,service的默认user就是root。
重启之后,发现第一连接成功,以为问题已经解决,重试若干次之后,发现问题依旧。
仔细对比可以发现,修改前后的最大差别就是客户端启动的时间。
通过上网查阅,发现,connect失败之后,socket句柄处于未知状态。可以在man手册中查阅到相关信息
connect(3) - Linux man page
If connect() fails, the state of the socket is unspecified. Conforming applications should close the file descriptor and create a new socket before attempting to reconnect.
于是,尝试在connect失败后,close 当前句柄,重新创建, 验证修改有效