android native socket correspond

    最近在做android native socket通信。主要在native這裡寫socket服務端的程序。根據client需求,通過PC端串口發送AT command,native負責接受從PC端發送的命令,過濾有效命令,通過socket發送到APP端,APP收到命令後進行相關測試,之後將測試信息返回native,native發送到PC端串口,顯示測試結果。
       native的socket服務端的實現原理:創建後臺服務,開啟一個進程,監聽串口消息。
       流程如下:
       1.在init.rc裡增加服務
       chown system system /dev/ttyGS0
       chmod 0666 /dev/ttyGS0     

      on property:ro.baseband="unknown"
      start at
 
      service at /system/bin/at 
      socket sockettest stream 0666 radio system
      user system
      group system inet
      disabled     

    2.native服務程序 /system/at/at.c
         #if 1
#define LOG_TAG "AT"
#define SOCKET_NAME "sockettest"
#include <utils/Log.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/un.h>
#include <cutils/sockets.h>
#include <fcntl.h> //open(), read(), write()
#define BUFSIZE 100
int count = 0;

#define LOGE(…) __android_log_print(ANDROID_LOG_ERROR, "myserver", __VA_ARGS__)

int main(){

#if 1
int connect_number = 4;
int fdListen = -1, new_fd = -1;
int fd, ret;
char ttyBuf[BUFSIZE];

char *msg = "";// "ttyGS0 test";
char *end = "\r\n";
struct sockaddr peeraddr;
socklen_t socklen = sizeof (peeraddr);
int numbytes ;
char buff[256];
fd_set fds;
int max = 0;
while(1){
fd = open("/dev/ttyGS0", O_RDWR);//打開usb serial device
//printf("envi serial test program\n");
LOGD("envi serial test program","myserver");
if(fd < 0)
{
//printf("\n");
LOGD("Error: open /dev/ttyGS0 error!","myserver");
return 1;
}

fdListen = android_get_control_socket(SOCKET_NAME);//創建native socket服務端本地連接
if (fdListen < 0) {
LOGD("Failed to get socket","myserver");
exit(-1);
}

LOGD("get","myserver");
ret = listen(fdListen, connect_number); //listen
if (ret < 0) {
LOGD("listen socket failed","myserver");
//perror("listen");
//exit(-1);
}
LOGD("geta","myserver");
//It block until client connected.accept(socket_id, &peeraddr, &socklen);
#if 1
new_fd = accept(fdListen, &peeraddr, &socklen); //與client端連接
if (new_fd < 0 ) {
//LOGD("Error on accept() errno:%d", errno);
LOGD("Error on accept()","myserver");
//perror("accept");
//exit(-1);
continue;
}
LOGD("getb","myserver");
//send at command from ttyGS0

while(1){
//read from ttyGS0
memset(ttyBuf, 0, sizeof(ttyBuf));
ret = read(fd, ttyBuf, BUFSIZE);
if(ret < 0)
{
//printf("Error: read device error!\n");
//return 1;
LOGD("Error: read device error","myserver",errno);
}
if(ttyBuf[0] != NULL){

LOGD("while count","myserver",ttyBuf[0]);
LOGD("myserver","yzy is " + ttyBuf[0]);
//strcat(ttyBuf, end);//add /r/n
if(send(new_fd, ttyBuf, strlen(ttyBuf), 0) < 0) {
LOGE("send failed");
}
LOGD("get1","myserver");
#if 1
FD_ZERO(&fds);
FD_SET(new_fd, &fds);
if(new_fd > max)
max = new_fd;
if(select(max + 1, &fds, NULL, NULL, NULL) < 0)//t進行讀操作
{
LOGE("select() failed","myserver");
}
if(FD_ISSET(new_fd, &fds)){
if((numbytes = recv(new_fd,buff,sizeof(buff),0))==-1)
{
LOGE("recv failed","myserver");
//perror("recv");
//exit(-1);
}
}
#endif

LOGD("get2","myserver");

if(numbytes > 0){
ret = write(fd, buff, strlen(buff));
if(ret < 0)
{
LOGD("write ttyGS0 error","myserver");
//return 1;
}
}
#endif
}
close(fd);
close(new_fd);
close(fdListen);
#endif
}
return 0;
}
#endif

3.APP端用localSocket來創建client端,用connect()函數來連接native socket server端。
LocalSocket ls = null;
LocalSocketAddress lsa;
ls = new LocalSocket();
lsa = new LocalSocketAddress(SOCKET_NAME,LocalSocketAddress.Namespace.RESERVED);//這裡的SOCKET_NAME必須與native和init.rc相同,為sockettest
ls.connect(lsa);
如果socket連上沒有問題,就可以收發消息瞭。

4.小結:native和framework的通信是通過jni,一般情況下是framework調用jni的。如果native有消息,怎麼樣讓framework知道呢?上面使用socket通信,可以讓framework和native相互通信。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *