NDK学习笔记(十一) POSIX Sockect 本地通信

2024-06-13 03:18

本文主要是介绍NDK学习笔记(十一) POSIX Sockect 本地通信,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 1.本地通信,原生服务端、java客户端
    • (1)函数介绍(C/C++)

1.本地通信,原生服务端、java客户端

这个例子中,原生代码实现了本地服务端,java代码实现了本地客户端。本地服务端使用了之前tcp通信的某些方法。

(1)函数介绍(C/C++)

创建原生本地socket

/*** 创建原生本地socket* @param env* @param obj* @return*/
static int NewLocalSocket(JNIEnv *env, jobject obj) {LogMessage(env, obj, "创建本地socket");int localSocket = socket(PF_LOCAL, SOCK_STREAM, 0);if (-1 == localSocket) {ThrowErrnoException(env, "java/io/IOException", errno);}return localSocket;
}

将本地socket与Name绑定

本地socket命名空间:
Abstract namespace:在本地socket通信协议模块中维护,socket名以NULL字符为前缀绑定socket名。
Filesystem namespace:通过文件系统以一个特殊socket文件的形式维护,socket名直接传递给sockaddr_un结构,将socket名与socket绑定。

/*** 将本地socket与某一名称绑定**/
static void BindLocalSocketToName(JNIEnv *env, jobject obj, int sd, const char *name) {struct sockaddr_un address;//长度const size_t nameLength = strlen(name);size_t pathLength = nameLength;//如果名字不以“/”开头,则在Abstract namespacebool abstractNamespace = ('/' != name[0]);//抽象命名空间要求目录的第一个字节是0字节,更新路径长度包括0字节if (abstractNamespace) {pathLength++;}if (pathLength > sizeof(address.sun_path)) {ThrowException(env, "java/io/IOException", "名字太长");} else {memset(&address, 0, sizeof(address));address.sun_family = PF_LOCAL;char *sunPath = address.sun_path;//第一字节必须是0以使用抽象命名空间if (abstractNamespace) {*sunPath++ = NULL;}strcpy(sunPath, name);//地址长度,offsetof会生成一个类型为 size_t 的整型常量,它是一个结构成员相对于结构开头的字节偏移量。socklen_t addressLength = (offsetof(struct sockaddr_un, sun_path)) + pathLength;//如果socket名已经绑定,取消连接unlink(address.sun_path);LogMessage(env, obj, "绑定到本地名称%s%s", (abstractNamespace) ? "(null)" : "", name);if (-1 == bind(sd, (struct sockaddr *) &address, addressLength)) {ThrowErrnoException(env, "java/io/IOException", errno);}}
}

接收本地socket

/*** 阻塞并等待socket上客户端的连接* @param env* @param obj* @param sd* @return*/
static int AcceptOnLocalSocket(JNIEnv *env, jobject obj, int sd) {LogMessage(env, obj, "等待客户端连接");int clientSocket = accept(sd, NULL, NULL);if (-1 == clientSocket) {ThrowErrnoException(env, "java/io/IOException", errno);}return clientSocket;
}

启动Socket Server

/*** 启动本地unix socket 服务器*/
extern "C"
JNIEXPORT void JNICALL
Java_com_example_testnt_LocalEchoActivity_nativeStartLocalServer(JNIEnv *env, jobject thiz,jstring name) {int serverSocket = NewLocalSocket(env, thiz);if (NULL == env->ExceptionOccurred()) {const char *nameText = env->GetStringUTFChars(name, NULL);if (NULL == nameText) {goto exit;}//绑定BindLocalSocketToName(env, thiz, serverSocket, nameText);env->ReleaseStringUTFChars(name, nameText);if (NULL != env->ExceptionOccurred()) {goto exit;}ListenOnSocket(env, thiz, serverSocket, 4);if (NULL != env->ExceptionOccurred()) {goto exit;}int clientSocket = AcceptOnLocalSocket(env, thiz, serverSocket);if (NULL != env->ExceptionOccurred()) {goto exit;}char buffer[MAX_BUFFER_SZIE];ssize_t recvSize;ssize_t sentSize;while (1) {recvSize = ReceiveFromSocket(env, thiz, clientSocket, buffer, MAX_BUFFER_SZIE);if ((0 == recvSize) || (NULL != env->ExceptionOccurred())) {break;}sentSize = SendToSocker(env, thiz, clientSocket, buffer, (size_t) recvSize);if ((0 == sentSize) || (NULL != env->ExceptionOccurred())) {break;}}close(clientSocket);}exit:if (serverSocket > 0) {close(serverSocket);}
}

运行效果
在这里插入图片描述
详细代码请看下面的连接,运行时启动LocalEchoActivity界面。

https://gitee.com/xd_box/NDK_Socket

这篇关于NDK学习笔记(十一) POSIX Sockect 本地通信的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1056123

相关文章

一文详解Git中分支本地和远程删除的方法

《一文详解Git中分支本地和远程删除的方法》在使用Git进行版本控制的过程中,我们会创建多个分支来进行不同功能的开发,这就容易涉及到如何正确地删除本地分支和远程分支,下面我们就来看看相关的实现方法吧... 目录技术背景实现步骤删除本地分支删除远程www.chinasem.cn分支同步删除信息到其他机器示例步骤

前端如何通过nginx访问本地端口

《前端如何通过nginx访问本地端口》:本文主要介绍前端如何通过nginx访问本地端口的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、nginx安装1、下载(1)下载地址(2)系统选择(3)版本选择2、安装部署(1)解压(2)配置文件修改(3)启动(4)

Java使用HttpClient实现图片下载与本地保存功能

《Java使用HttpClient实现图片下载与本地保存功能》在当今数字化时代,网络资源的获取与处理已成为软件开发中的常见需求,其中,图片作为网络上最常见的资源之一,其下载与保存功能在许多应用场景中都... 目录引言一、Apache HttpClient简介二、技术栈与环境准备三、实现图片下载与保存功能1.

Go学习记录之runtime包深入解析

《Go学习记录之runtime包深入解析》Go语言runtime包管理运行时环境,涵盖goroutine调度、内存分配、垃圾回收、类型信息等核心功能,:本文主要介绍Go学习记录之runtime包的... 目录前言:一、runtime包内容学习1、作用:① Goroutine和并发控制:② 垃圾回收:③ 栈和

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

RabbitMQ工作模式中的RPC通信模式详解

《RabbitMQ工作模式中的RPC通信模式详解》在RabbitMQ中,RPC模式通过消息队列实现远程调用功能,这篇文章给大家介绍RabbitMQ工作模式之RPC通信模式,感兴趣的朋友一起看看吧... 目录RPC通信模式概述工作流程代码案例引入依赖常量类编写客户端代码编写服务端代码RPC通信模式概述在R

在Spring Boot中实现HTTPS加密通信及常见问题排查

《在SpringBoot中实现HTTPS加密通信及常见问题排查》HTTPS是HTTP的安全版本,通过SSL/TLS协议为通讯提供加密、身份验证和数据完整性保护,下面通过本文给大家介绍在SpringB... 目录一、HTTPS核心原理1.加密流程概述2.加密技术组合二、证书体系详解1、证书类型对比2. 证书获

Java实现本地缓存的常用方案介绍

《Java实现本地缓存的常用方案介绍》本地缓存的代表技术主要有HashMap,GuavaCache,Caffeine和Encahche,这篇文章主要来和大家聊聊java利用这些技术分别实现本地缓存的方... 目录本地缓存实现方式HashMapConcurrentHashMapGuava CacheCaffe

Maven项目打包时添加本地Jar包的操作步骤

《Maven项目打包时添加本地Jar包的操作步骤》在Maven项目开发中,我们经常会遇到需要引入本地Jar包的场景,比如使用未发布到中央仓库的第三方库或者处理版本冲突的依赖项,本文将详细介绍如何通过M... 目录一、适用场景说明​二、核心操作命令​1. 命令格式解析​2. 实战案例演示​三、项目配置步骤​1

使用Python实现调用API获取图片存储到本地的方法

《使用Python实现调用API获取图片存储到本地的方法》开发一个自动化工具,用于从JSON数据源中提取图像ID,通过调用指定API获取未经压缩的原始图像文件,并确保下载结果与Postman等工具直接... 目录使用python实现调用API获取图片存储到本地1、项目概述2、核心功能3、环境准备4、代码实现