android的NDK和java进行本地socket通信

  关于Android应用与Framework的socket通信,相信关心这个问题的朋友们已经看过《android使用socket使底层和framework通信》这篇文章,美中不足的是作者只贴出一些关键的代码片段而并没有放出源码。我这里还是以一个能实际运行的例子为基础来讲,这样也方便大家学习。

    首先看一下效果,如下图。我填写姓名"Potter",选择性别"Mr"然后点击发送,底层socket收到消息后将消息直接返回给我,我将返回的结果(Mr.Potter)直接显示在Result。

编写socket服务端代码,生成可执行脚本htfsk。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#define SOCKET_NAME "htfsk"
 
#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 <utils/Log.h>
#include <android/log.h>
 
 
int main(){
     char log [200];
 
     int connect_number = 6;
     int fdListen = -1, new_fd = -1;
     int ret;
     struct sockaddr_un peeraddr;
     socklen_t socklen = sizeof (peeraddr);
     int numbytes ;
     char buff[256];
     //这一步很关键,就是获取init.rc中配置的名为 "htfsk" 的socket
     fdListen = android_get_control_socket(SOCKET_NAME);
     if (fdListen < 0) {
     sprintf ( log , "Failed to get socket '" SOCKET_NAME "' errno:%d" , errno );
     __android_log_write(ANDROID_LOG_DEBUG, "FTM_JNI" , log );
     exit (-1);
     }
     //开始监听
     ret = listen(fdListen, connect_number);   
     
     sprintf ( log , "Listen result %d" ,ret);
     __android_log_write(ANDROID_LOG_DEBUG, "FTM_JNI" , log );
     
     if (ret < 0) {
         perror ( "listen" );
         exit (-1);
     }
     //等待Socket客户端发启连接请求
     new_fd = accept(fdListen, ( struct sockaddr *) &peeraddr, &socklen);
     sprintf ( log , "Accept_fd %d" ,new_fd);
     __android_log_write(ANDROID_LOG_DEBUG, "FTM_JNI" , log );
     if (new_fd < 0 ) {
         sprintf ( log , "%d" , errno );
         __android_log_write(ANDROID_LOG_DEBUG, "FTM_JNI" , log );
         perror ( "accept error" );
         exit (-1);
     }
     
     while (1){
     //循环等待Socket客户端发来消息
     __android_log_write(ANDROID_LOG_DEBUG, "FTM_JNI" , "Waiting for receive" );
     if ((numbytes = recv(new_fd,buff, sizeof (buff),0))==-1){
         sprintf ( log , "%d" , errno );
         __android_log_write(ANDROID_LOG_DEBUG, "FTM_JNI" , log );
         perror ( "recv" );
         continue ;
     }
     //发送消息回执给Socket客户端
     if (send(new_fd,buff, strlen (buff),0)==-1)
     {
         perror ( "send" );
         close(new_fd);
         exit (0);
     }      
     }
     
     close(new_fd);
     close(fdListen);
     return 0;
}

3、编写客户端java代码。核心代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
 
import android.net.LocalSocket;
import android.net.LocalSocketAddress;
import android.util.Log;
 
/**
  * Socket客户端
  *
  * @author lai_zs
  * @date:2012-3-17 下午12:15:09
  */
public class SocketClient {
     private final String SOCKET_NAME = "htfsk" ;
     private LocalSocket client;
     private LocalSocketAddress address;
     private boolean isConnected = false ;
     private int connetTime = 1 ;
 
     public SocketClient() {
         client = new LocalSocket();
         address = new LocalSocketAddress(SOCKET_NAME, LocalSocketAddress.Namespace.RESERVED);
         new ConnectSocketThread().start();
     }
 
     /**
      * 发送消息
      * @param msg
      * @return 返回Socket服务端的消息回执
      */
     public String sendMsg(String msg) {
         if (!isConnected) {
             return "Connect fail" ;
         }
         try {
             BufferedReader in = new BufferedReader( new InputStreamReader(client.getInputStream()));
             PrintWriter out = new PrintWriter(client.getOutputStream());
             out.println(msg);
             out.flush();
             return in.readLine();
         } catch (IOException e) {
             e.printStackTrace();
         }
         return "Nothing return" ;
     }
 
     /**
      * 异步连接Socket,如果连接不上会尝试重复连接十次
      *
      * @author Administrator
      *
      */
     private class ConnectSocketThread extends Thread {
         @Override
         public void run() {
             while (!isConnected && connetTime <= 10 ) {
                 try {
                     sleep( 1000 );
                     Log.i( "SocketClient" , "Try to connect socket;ConnectTime:" +connetTime);
                     client.connect(address);
                     isConnected = true ;
                 } catch (Exception e) {
                     connetTime++;
                     isConnected = false ;
                     Log.i( "SocketClient" , "Connect fail" );
                 }
             }
         }
     }
 
     /**
      * 关闭Socket
      */
     public void closeSocket() {
         try {
             client.close();
         } catch (IOException e) {
             e.printStackTrace();
         }
     }
 
}

其它相关文章连接汇总:

android native c java进行本地socket通信
http://blog.csdn.net/weidawei0609/article/details/7327626
android使用socket使底层和framework通信  
http://fanwei51880.blog.163.com/blog/static/32406740201011150240981/
Android应用与framework的socket通信实例   -- 推荐
http://blog.csdn.net/goleftgoright/article/details/7406292
【android】Socket简单用法
http://www.cnblogs.com/harrisonpc/archive/2011/03/31/2001565.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值