zoukankan      html  css  js  c++  java
  • android的NDK和java进行本地socket通信

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

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

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

    #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代码。核心代码如下:

    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();
    		}
    	}
    
    }
     
  • 相关阅读:
    SQL数据库数据优化SQL优化总结( 百万级数据库优化方案)
    三星S8相机黑画面解决
    三星Galaxy S8 刷机经验记录
    2018.12.02 Socket编程之初识Socket
    工作至今
    巧用std::shared_ptr全局对象释放单例内存
    C++标准库之迭代器
    Phone 3rd Recovery
    进电机之两相双极性步进电机仿真
    使用Pretues仿真Arduino驱动步进电机
  • 原文地址:https://www.cnblogs.com/xiaochao1234/p/3699663.html
Copyright © 2011-2022 走看看