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

相关文章

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

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

java连接opcua的常见问题及解决方法

《java连接opcua的常见问题及解决方法》本文将使用EclipseMilo作为示例库,演示如何在Java中使用匿名、用户名密码以及证书加密三种方式连接到OPCUA服务器,若需要使用其他SDK,原理... 目录一、前言二、准备工作三、匿名方式连接3.1 匿名方式简介3.2 示例代码四、用户名密码方式连接4

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

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

MySQL 表的内外连接案例详解

《MySQL表的内外连接案例详解》本文给大家介绍MySQL表的内外连接,结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录表的内外连接(重点)内连接外连接表的内外连接(重点)内连接内连接实际上就是利用where子句对两种表形成的笛卡儿积进行筛选,我

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

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

Apache 高级配置实战之从连接保持到日志分析的完整指南

《Apache高级配置实战之从连接保持到日志分析的完整指南》本文带你从连接保持优化开始,一路走到访问控制和日志管理,最后用AWStats来分析网站数据,对Apache配置日志分析相关知识感兴趣的朋友... 目录Apache 高级配置实战:从连接保持到日志分析的完整指南前言 一、Apache 连接保持 - 性

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

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

电脑蓝牙连不上怎么办? 5 招教你轻松修复Mac蓝牙连接问题的技巧

《电脑蓝牙连不上怎么办?5招教你轻松修复Mac蓝牙连接问题的技巧》蓝牙连接问题是一些Mac用户经常遇到的常见问题之一,在本文章中,我们将提供一些有用的提示和技巧,帮助您解决可能出现的蓝牙连接问... 蓝牙作为一种流行的无线技术,已经成为我们连接各种设备的重要工具。在 MAC 上,你可以根据自己的需求,轻松地

宝塔安装的MySQL无法连接的情况及解决方案

《宝塔安装的MySQL无法连接的情况及解决方案》宝塔面板是一款流行的服务器管理工具,其中集成的MySQL数据库有时会出现连接问题,本文详细介绍两种最常见的MySQL连接错误:“1130-Hostisn... 目录一、错误 1130:Host ‘xxx.xxx.xxx.xxx’ is not allowed

Python模拟串口通信的示例详解

《Python模拟串口通信的示例详解》pySerial是Python中用于操作串口的第三方模块,它支持Windows、Linux、OSX、BSD等多个平台,下面我们就来看看Python如何使用pySe... 目录1.win 下载虚www.chinasem.cn拟串口2、确定串口号3、配置串口4、串口通信示例5