当前位置: 首页 > news >正文

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();
		}
	}

}

 

 

转载于:https://www.cnblogs.com/xiaochao1234/p/3699663.html

相关文章:

  • Hadoop学习笔记3:org.apache.hadoop.conf
  • 远程桌面与远程控制
  • [leetcode] Balanced Binary Tree
  • 运维的我要学开发--Python(4)
  • Ubuntu 14.04配置记录
  • 【笔记】设计模式——装饰者模式
  • IsBadStringPtr、IsBadWritePtr
  • OC语言BLOCK和协议
  • js学习记录
  • C++容器操作
  • .Net 转战 Android 4.4 日常笔记(4)--按钮事件和国际化
  • 引用动态链接库Dll文件 引用失败 未能添加对HD.dll的引用。请确保此文件可访问并且是一个有效的程序集或COM组件...
  • IOS 基于APNS消息推送原理与实现(JAVA后台)--转
  • asp.net解决:当前上下文中不存在名称“Session”
  • thinkphp问题记录phpQuery使用错误
  • [译] React v16.8: 含有Hooks的版本
  • 《剑指offer》分解让复杂问题更简单
  • 30天自制操作系统-2
  • Apache的基本使用
  • CSS相对定位
  • javascript从右向左截取指定位数字符的3种方法
  • Mithril.js 入门介绍
  • niucms就是以城市为分割单位,在上面 小区/乡村/同城论坛+58+团购
  • sessionStorage和localStorage
  • windows-nginx-https-本地配置
  • 代理模式
  • 工程优化暨babel升级小记
  • 构造函数(constructor)与原型链(prototype)关系
  • 排序算法学习笔记
  • 区块链共识机制优缺点对比都是什么
  • 如何选择开源的机器学习框架?
  • # Maven错误Error executing Maven
  • #define、const、typedef的差别
  • #NOIP 2014# day.2 T2 寻找道路
  • #NOIP 2014#Day.2 T3 解方程
  • (20050108)又读《平凡的世界》
  • (C语言)字符分类函数
  • (分布式缓存)Redis哨兵
  • (附源码)springboot工单管理系统 毕业设计 964158
  • (黑马出品_高级篇_01)SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式
  • (亲测)设​置​m​y​e​c​l​i​p​s​e​打​开​默​认​工​作​空​间...
  • (四)Tiki-taka算法(TTA)求解无人机三维路径规划研究(MATLAB)
  • (总结)Linux下的暴力密码在线破解工具Hydra详解
  • *Algs4-1.5.25随机网格的倍率测试-(未读懂题)
  • .“空心村”成因分析及解决对策122344
  • .FileZilla的使用和主动模式被动模式介绍
  • .net core 连接数据库,通过数据库生成Modell
  • .net core 依赖注入的基本用发
  • .net framework4与其client profile版本的区别
  • .net 前台table如何加一列下拉框_如何用Word编辑参考文献
  • .NET 同步与异步 之 原子操作和自旋锁(Interlocked、SpinLock)(九)
  • .NET/C# 检测电脑上安装的 .NET Framework 的版本
  • .NET/C# 利用 Walterlv.WeakEvents 高性能地中转一个自定义的弱事件(可让任意 CLR 事件成为弱事件)
  • .Net小白的大学四年,内含面经
  • .NET中两种OCR方式对比