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

相关文章

在java中如何将inputStream对象转换为File对象(不生成本地文件)

《在java中如何将inputStream对象转换为File对象(不生成本地文件)》:本文主要介绍在java中如何将inputStream对象转换为File对象(不生成本地文件),具有很好的参考价... 目录需求说明问题解决总结需求说明在后端中通过POI生成Excel文件流,将输出流(outputStre

SpringBoot配置Ollama实现本地部署DeepSeek

《SpringBoot配置Ollama实现本地部署DeepSeek》本文主要介绍了在本地环境中使用Ollama配置DeepSeek模型,并在IntelliJIDEA中创建一个Sprin... 目录前言详细步骤一、本地配置DeepSeek二、SpringBoot项目调用本地DeepSeek前言随着人工智能技

OpenManus本地部署实战亲测有效完全免费(最新推荐)

《OpenManus本地部署实战亲测有效完全免费(最新推荐)》文章介绍了如何在本地部署OpenManus大语言模型,包括环境搭建、LLM编程接口配置和测试步骤,本文给大家讲解的非常详细,感兴趣的朋友一... 目录1.概况2.环境搭建2.1安装miniconda或者anaconda2.2 LLM编程接口配置2

Java进阶学习之如何开启远程调式

《Java进阶学习之如何开启远程调式》Java开发中的远程调试是一项至关重要的技能,特别是在处理生产环境的问题或者协作开发时,:本文主要介绍Java进阶学习之如何开启远程调式的相关资料,需要的朋友... 目录概述Java远程调试的开启与底层原理开启Java远程调试底层原理JVM参数总结&nbsMbKKXJx

在VSCode中本地运行DeepSeek的流程步骤

《在VSCode中本地运行DeepSeek的流程步骤》本文详细介绍了如何在本地VSCode中安装和配置Ollama和CodeGPT,以使用DeepSeek进行AI编码辅助,无需依赖云服务,需要的朋友可... 目录步骤 1:在 VSCode 中安装 Ollama 和 CodeGPT安装Ollama下载Olla

C#集成DeepSeek模型实现AI私有化的流程步骤(本地部署与API调用教程)

《C#集成DeepSeek模型实现AI私有化的流程步骤(本地部署与API调用教程)》本文主要介绍了C#集成DeepSeek模型实现AI私有化的方法,包括搭建基础环境,如安装Ollama和下载DeepS... 目录前言搭建基础环境1、安装 Ollama2、下载 DeepSeek R1 模型客户端 ChatBo

JAVA集成本地部署的DeepSeek的图文教程

《JAVA集成本地部署的DeepSeek的图文教程》本文主要介绍了JAVA集成本地部署的DeepSeek的图文教程,包含配置环境变量及下载DeepSeek-R1模型并启动,具有一定的参考价值,感兴趣的... 目录一、下载部署DeepSeek1.下载ollama2.下载DeepSeek-R1模型并启动 二、J

0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型的操作流程

《0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeekR1模型的操作流程》DeepSeekR1模型凭借其强大的自然语言处理能力,在未来具有广阔的应用前景,有望在多个领域发... 目录0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型,3步搞定一个应

Java深度学习库DJL实现Python的NumPy方式

《Java深度学习库DJL实现Python的NumPy方式》本文介绍了DJL库的背景和基本功能,包括NDArray的创建、数学运算、数据获取和设置等,同时,还展示了如何使用NDArray进行数据预处理... 目录1 NDArray 的背景介绍1.1 架构2 JavaDJL使用2.1 安装DJL2.2 基本操

一文教你使用Python实现本地分页

《一文教你使用Python实现本地分页》这篇文章主要为大家详细介绍了Python如何实现本地分页的算法,主要针对二级数据结构,文中的示例代码简洁易懂,有需要的小伙伴可以了解下... 在项目开发的过程中,遇到分页的第一页就展示大量的数据,导致前端列表加载展示的速度慢,所以需要在本地加入分页处理,把所有数据先放