21.11.18 Android socket作业

21.11.18 Android socket作业,第1张

21.11.18 Android socket作业

1. 作业内容

        用socket实现Android client和Android server之间的通信,通过client的命令行给server传递client的进程id和想要传递的字符串,且通过apk的toast将命令行传递来的内容在测试机上show出。

2. 分步解决

        (1)Android socket实现client和server之间的通信

                Android系统在Unix socket的基础上做了封装,构成了自己的一套Socket。要使用它需要将对应的头文件(cutils/sockets.h)包含进来。

                有关Android socket通信,ppt中给出了server端和client端的关键代码:

//server关键代码
server_fd=android_get_control_socket("socket_name");
ret=listen(server_fd,4);
while((socket=accept(server_fd,(sockaddr*)&peeraddr,&sockle))>=0)
read/write(socket,"hello",5);.....//send or write
//client端
fd=socket_local_client("socket_name",ANDROID_SOCKET_NAMESPACE_RESERVED,SOCK_STREAM);
if(fd>=0) read/write(fd,"hello",5);

               这是c代码,因此我们首先在vendor下某个目录中新建一个子目录,并新建两个文件:ran_client.c 和 ran_server.c 。client端相对来说比较简单,只需要使用socket_locat_client()函数链接至套接字后用write函数写入数据即可。结合题意使用getpid获取进程id,使用gets()函数接收键盘输入的string,用strcat把这两个内容拼接后一起传入socket中。

                对于server端,android_get_control_socket("name")相当于创建了一个socket(也可以理解为连接上以ran_socket为名的socket。listen指对该进程进行监听,此后使用while进入等待socket信息的循环。在收到信息后,使用read函数读取出来socket传递来的数据,再对数据进行下一步的处理。

        (2)am broadcast命令

                am命令可以直接控制apk。常见的am命令有:

                am start -n [apkname]        //控制开启apk

                结合broadcast广播,可以使用am broadcast -a [apkname] -f [flags] --es [name] [string]命令将string和传入[name]中,apk中就能接收到。

        (3)system函数

                am broadcast的问题解决了,就要解决如何在ran_server.c中执行这条程序了。c语言调用system(char* command)函数,可以在括号中输入需要在shell命令行执行的语句。如system("getprop | grep -i ran_");

                需要注意的是,这里system里的内容对于c语言来说仅仅是一串字符串,因此无法在其中进行任何的读取数据等 *** 作。本题中,需要把server端接收到的数据传递进command中,只能提前读取出数据内容,用strcpy和strcat将内容与对应数据进行拼接再传入system中。

        (4).rc和.mk文件设置

                在.rc中增加一个ran_server的service,在其中提前申请一个socket,赋予权限并设置在fs-fata下自启动。从其他地方借来一个label给它执行权限。

#ran
service ran_server /system/bin/ran_server
    socket ran_server_socket stream 0660 root system
    seclabel u:r:asus_bluetooth:s0
    class core
    user root
    group root
    oneshot

                要使得c文件最终变成可在手机中执行的.ko驱动文件,还需要创建一个Android.mk文件。(这里的mk文件复制于其他类似mk,只改了module名字和部分lib库。)

3. 遇到的问题

        (1)在包含头文件时候报错文件不存在。因为mk文件中没有把对应的lib库包含进来,在mk中添加对应lib后解决了问题。

include $(CLEAR_VARS)
LOCAL_SHARED_LIBRARIES := 
        libutils 
        libcutils 
        liblog
LOCAL_SRC_FILES := ran_server.c

         (2)在使用am broadcast时,一开始并没有加-f ,这时候查看log会发现报broadcast not allowed权限不足的错。查询资料得知,Android 8之后对broadcast发送的信息管控更加严格了,有些没有加flag的传送信号会被自动拦截下来。加上-f 0x1000000后解决了这个问题。

        (3)一度有过avc报错,虽然后来发现执行失败和avc报错没有关系(selinux已经关闭),还是记录一下如何解决avc报错。 首先,rc中对自己创建的service打了label,那么去对应的te文件中添加权限(又称解sepolicy)。命令:

avc报错:avc:denied {[权限]} for path = "..." dev = "...", ino = ... scontext=[执行者] tcontext = [被执行者] tclass=[被执行者类型] permissive = 0

allow [执行者] [被执行者] : [被执行者类型] {[权限]}

        完成后,先执行make sepolicy 来确认改动无错,再执行make vendorimage后刷入vendor。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5563574.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-14
下一篇 2022-12-14

发表评论

登录后才能评论

评论列表(0条)

保存