NDK学习笔记(十) POSIX Sockect 面向无连接的通信

2024-06-13 03:18

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

文章目录

  • 1.接收数据报
  • 2.发送数据报
  • 3.udp服务
  • 4.udp客户端

下面只是代码片段,想看详细的代码请clone代码。
本人没有在android虚拟机上看到通信成功,试了好多配置依然不行,过段时间找两个手机再试试。
运行项目时,如果要看tcp的,则需要更改ClientTask、ServerTask类中的onBackground方法,将jni方法替换成tcp的。udp的也一样,udp的则替换成udp的jni方法。

地址:https://gitee.com/xd_box/NDK_Socket

1.接收数据报

__fd:socket实例
__buf:保存从socket接收的数据
__n:缓冲区大小
__flags:额外标志
__src_addr:保存客户端发送包的协议地址
__src_addr_length:协议地址的内存空间大小成功返回接收到的字节数,失败返回-1
__socketcall ssize_t recvfrom(int __fd, void* __buf, size_t __n, int __flags, struct sockaddr* __src_addr, socklen_t* __src_addr_length);
static ssize_t ReceiveDatagramFromSocket(JNIEnv *env, jobject obj, int sd,struct sockaddr_in *address, char *buffer,size_t bufferSize) {socklen_t addressLength = sizeof(struct sockaddr_in);//从socket中接受数据包LogMessage(env, obj, "从socket接受数据");ssize_t recvSize = recvfrom(sd, buffer, bufferSize, 0, (struct sockaddr *) address,&addressLength);if (-1 == recvSize) {ThrowErrnoException(env, "java/io/IOException", errno);} else {LogAddress(env, obj, "接收到", address);//以NULL种植缓冲区使其为一个字符串buffer[recvSize] = NULL;if (recvSize > 0) {LogMessage(env, obj, "接收到%d字节:%s", recvSize, buffer);}}return recvSize;
}

2.发送数据报

__fd:socket实例
__buf:要发送的数据的指针
__n:缓冲区大小
__flags:额外标志
__dst_addr:目标地址
__dst_addr_length:地址结构大小成功返回传送的字节数,失败但会-1
__socketcall ssize_t sendto(int __fd, const void* __buf, size_t __n, int __flags, const struct sockaddr* __dst_addr, socklen_t __dst_addr_length);
static ssize_t SendDatagramToSpcket(JNIEnv *env, jobject obj, int sd,const struct sockaddr_in *address, const char *buffer,size_t bufferSize) {LogAddress(env, obj, "Sending to", address);ssize_t sentSize = sendto(sd, buffer, bufferSize, 0, (const sockaddr *) address,sizeof(struct sockaddr_in));if (-1 == sentSize) {ThrowErrnoException(env, "java/io/IOException", errno);} else if (sentSize > 0) {LogMessage(env, obj, "sent %d 字节:%s", sentSize, buffer);}return sentSize;
}

3.udp服务

开启udp服务

extern "C"
JNIEXPORT void JNICALL
Java_com_example_testnt_EchoServerActivity_nativeStartUdpServer(JNIEnv *env, jobject thiz,jint port) {int serverSocket = NewUdpSocket(env, thiz);if (NULL == env->ExceptionOccurred()) {BindSocketToPort(env, thiz, serverSocket, (unsigned short) port);if (NULL != env->ExceptionOccurred()) {goto exit;}if (0 == port) {GetSocketPort(env, thiz, serverSocket);if (NULL != env->ExceptionOccurred()) {goto exit;}}struct sockaddr_in address;memset(&address, 0, sizeof(address));char buffer[MAX_BUFFER_SZIE];ssize_t recvSize;ssize_t sentSize;//接收recvSize = ReceiveDatagramFromSocket(env, thiz, serverSocket, &address, buffer,MAX_BUFFER_SZIE);if ((0 == recvSize) || (NULL != env->ExceptionOccurred())) {goto exit;}sentSize = SendDatagramToSpcket(env, thiz, serverSocket, &address, buffer,(size_t) recvSize);if ((0 == sentSize) || (NULL != env->ExceptionOccurred())) {goto exit;}}exit:if (serverSocket > 0) {close(serverSocket);}
}

4.udp客户端

extern "C"
JNIEXPORT void JNICALL
Java_com_example_testnt_EchoClientActivity_nativeStartUdpClient(JNIEnv *env, jobject thiz,jstring ip, jint port,jstring message) {int clientSocket = NewUdpSocket(env, thiz);if (NULL == env->ExceptionOccurred()) {struct sockaddr_in address;memset(&address, 0, sizeof(address));address.sin_family = PF_INET;const char *ipAddress = env->GetStringUTFChars(ip, NULL);if (NULL == ipAddress) {goto exit;}//将IP地址字符串转换为网络地址int result = inet_aton(ipAddress, &(address.sin_addr));env->ReleaseStringUTFChars(ip, ipAddress);if (0 == result) {ThrowErrnoException(env, "java/io/IOException", errno);goto exit;}//转换为网络字节顺序address.sin_port = htons(port);const char *messageText = env->GetStringUTFChars(message, NULL);if (NULL == messageText) {goto exit;}jsize messageSize = env->GetStringUTFLength(message);//发送SendDatagramToSpcket(env, thiz, clientSocket, &address, messageText, (size_t) messageSize);env->ReleaseStringUTFChars(message, messageText);//失败if (NULL != env->ExceptionOccurred()) {goto exit;}char buffer[MAX_BUFFER_SZIE];memset(&address, 0, sizeof(address));ReceiveDatagramFromSocket(env, thiz, clientSocket, &address, buffer, MAX_BUFFER_SZIE);}exit:if (clientSocket > 0) {close(clientSocket);}
}

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



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

相关文章

java.sql.SQLTransientConnectionException连接超时异常原因及解决方案

《java.sql.SQLTransientConnectionException连接超时异常原因及解决方案》:本文主要介绍java.sql.SQLTransientConnectionExcep... 目录一、引言二、异常信息分析三、可能的原因3.1 连接池配置不合理3.2 数据库负载过高3.3 连接泄漏

Mac电脑如何通过 IntelliJ IDEA 远程连接 MySQL

《Mac电脑如何通过IntelliJIDEA远程连接MySQL》本文详解Mac通过IntelliJIDEA远程连接MySQL的步骤,本文通过图文并茂的形式给大家介绍的非常详细,感兴趣的朋友跟... 目录MAC电脑通过 IntelliJ IDEA 远程连接 mysql 的详细教程一、前缀条件确认二、打开 ID

Unity新手入门学习殿堂级知识详细讲解(图文)

《Unity新手入门学习殿堂级知识详细讲解(图文)》Unity是一款跨平台游戏引擎,支持2D/3D及VR/AR开发,核心功能模块包括图形、音频、物理等,通过可视化编辑器与脚本扩展实现开发,项目结构含A... 目录入门概述什么是 UnityUnity引擎基础认知编辑器核心操作Unity 编辑器项目模式分类工程

Go语言连接MySQL数据库执行基本的增删改查

《Go语言连接MySQL数据库执行基本的增删改查》在后端开发中,MySQL是最常用的关系型数据库之一,本文主要为大家详细介绍了如何使用Go连接MySQL数据库并执行基本的增删改查吧... 目录Go语言连接mysql数据库准备工作安装 MySQL 驱动代码实现运行结果注意事项Go语言执行基本的增删改查准备工作

python连接sqlite3简单用法完整例子

《python连接sqlite3简单用法完整例子》SQLite3是一个内置的Python模块,可以通过Python的标准库轻松地使用,无需进行额外安装和配置,:本文主要介绍python连接sqli... 目录1. 连接到数据库2. 创建游标对象3. 创建表4. 插入数据5. 查询数据6. 更新数据7. 删除

Python学习笔记之getattr和hasattr用法示例详解

《Python学习笔记之getattr和hasattr用法示例详解》在Python中,hasattr()、getattr()和setattr()是一组内置函数,用于对对象的属性进行操作和查询,这篇文章... 目录1.getattr用法详解1.1 基本作用1.2 示例1.3 原理2.hasattr用法详解2.

在 Spring Boot 中连接 MySQL 数据库的详细步骤

《在SpringBoot中连接MySQL数据库的详细步骤》本文介绍了SpringBoot连接MySQL数据库的流程,添加依赖、配置连接信息、创建实体类与仓库接口,通过自动配置实现数据库操作,... 目录一、添加依赖二、配置数据库连接三、创建实体类四、创建仓库接口五、创建服务类六、创建控制器七、运行应用程序八

解决hive启动时java.net.ConnectException:拒绝连接的问题

《解决hive启动时java.net.ConnectException:拒绝连接的问题》Hadoop集群连接被拒,需检查集群是否启动、关闭防火墙/SELinux、确认安全模式退出,若问题仍存,查看日志... 目录错误发生原因解决方式1.关闭防火墙2.关闭selinux3.启动集群4.检查集群是否正常启动5.

在Linux系统上连接GitHub的方法步骤(适用2025年)

《在Linux系统上连接GitHub的方法步骤(适用2025年)》在2025年,使用Linux系统连接GitHub的推荐方式是通过SSH(SecureShell)协议进行身份验证,这种方式不仅安全,还... 目录步骤一:检查并安装 Git步骤二:生成 SSH 密钥步骤三:将 SSH 公钥添加到 github

Redis客户端连接机制的实现方案

《Redis客户端连接机制的实现方案》本文主要介绍了Redis客户端连接机制的实现方案,包括事件驱动模型、非阻塞I/O处理、连接池应用及配置优化,具有一定的参考价值,感兴趣的可以了解一下... 目录1. Redis连接模型概述2. 连接建立过程详解2.1 连php接初始化流程2.2 关键配置参数3. 最大连