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

相关文章

Xshell远程连接失败以及解决方案

《Xshell远程连接失败以及解决方案》本文介绍了在Windows11家庭版和CentOS系统中解决Xshell无法连接远程服务器问题的步骤,在Windows11家庭版中,需要通过设置添加SSH功能并... 目录一.问题描述二.原因分析及解决办法2.1添加ssh功能2.2 在Windows中开启ssh服务2

Redis连接失败:客户端IP不在白名单中的问题分析与解决方案

《Redis连接失败:客户端IP不在白名单中的问题分析与解决方案》在现代分布式系统中,Redis作为一种高性能的内存数据库,被广泛应用于缓存、消息队列、会话存储等场景,然而,在实际使用过程中,我们可能... 目录一、问题背景二、错误分析1. 错误信息解读2. 根本原因三、解决方案1. 将客户端IP添加到Re

Mysql 中的多表连接和连接类型详解

《Mysql中的多表连接和连接类型详解》这篇文章详细介绍了MySQL中的多表连接及其各种类型,包括内连接、左连接、右连接、全外连接、自连接和交叉连接,通过这些连接方式,可以将分散在不同表中的相关数据... 目录什么是多表连接?1. 内连接(INNER JOIN)2. 左连接(LEFT JOIN 或 LEFT

Spring Boot实现多数据源连接和切换的解决方案

《SpringBoot实现多数据源连接和切换的解决方案》文章介绍了在SpringBoot中实现多数据源连接和切换的几种方案,并详细描述了一个使用AbstractRoutingDataSource的实... 目录前言一、多数据源配置与切换方案二、实现步骤总结前言在 Spring Boot 中实现多数据源连接

QT实现TCP客户端自动连接

《QT实现TCP客户端自动连接》这篇文章主要为大家详细介绍了QT中一个TCP客户端自动连接的测试模型,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录版本 1:没有取消按钮 测试效果测试代码版本 2:有取消按钮测试效果测试代码版本 1:没有取消按钮 测试效果缺陷:无法手动停

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

W外链微信推广短连接怎么做?

制作微信推广链接的难点分析 一、内容创作难度 制作微信推广链接时,首先需要创作有吸引力的内容。这不仅要求内容本身有趣、有价值,还要能够激起人们的分享欲望。对于许多企业和个人来说,尤其是那些缺乏创意和写作能力的人来说,这是制作微信推广链接的一大难点。 二、精准定位难度 微信用户群体庞大,不同用户的需求和兴趣各异。因此,制作推广链接时需要精准定位目标受众,以便更有效地吸引他们点击并分享链接

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;