文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Openharmony标准系统L2 JS、eTS 的napi socket 网络接口开发 TCP

2024-12-02 04:09

关注

​想了解更多内容,请访问:​

​51CTO和华为官方合作共建的鸿蒙技术社区​

​https://ost.51cto.com​

1、设计背景

当前openharmony标准系统通过 JS、eTS 开发貌似还没支持网络开发的接口,故JS、eTS。

方式开发只能通过NAPI调用C/C++才能使用到网络,本次我就使用NAPI开发openharmony APP 的网络编程开发!

①.openharmony APP 本次采用eTS开发方式。

②.本次实验是基于已连接上网络的。

③.openharmony APP 开发环境为 DevEco Studio 3.0.0.800。

④.使用的系统版本openharmony3.0 标准系统。

2、openharmony标准系统网络编程整体构思

①.本Demo简单的建立一个简单的socket server TCP。

②.通过C 实现 4个NAPI接口。

③设置一个简单的eTS APP使用NAPI网络接口。

3、napi代码实现部分

①.代码部分。

路径:\OpenHarmony\foundation\ace\napi\sample\native_module_socket_server\native_module_socket_server.cpp。

注意:native_module_socket_server文件夹自行创建。


#include "napi/native_api.h"
#include "napi/native_node_api.h"
#include "utils/log.h"
#include <stdlib.h> // standard library 标准库函数头文件
#include <stdio.h> // standard input output 标准输入输出函数
#include <stdint.h> // 定义了扩展的整数类型和宏
#include <unistd.h> // POSIX 系统 API 访问功能的头文件
#include <fcntl.h> // unix标准中通用的头文件 define O_WRONLY and O_RDONLY
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <string.h>
#include <signal.h>
static char buf[1024];
static size_t buflen;
static int wflag;
static int st;
static int client_st;
static napi_ref CallbackReff;
static napi_env envs;
void* socketserverthrd(void *ptr)
{
napi_value jsObj, prop1,prop2,prop3, callback = nullptr,undefine = nullptr;
napi_get_reference_value(envs, CallbackReff, &callback);
int port = 18000;
st = socket(AF_INET, SOCK_STREAM, 0);
int opt = SO_REUSEADDR;
setsockopt(st, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(st, (struct sockaddr *) &addr, sizeof(addr)) == -1)
{
HILOG_INFO("test0002 bind failed %s\n", strerror(errno));
return NULL;
}
if (listen(st, 20) == -1)
{
HILOG_INFO("test0002 listen failed %s\n", strerror(errno));
return NULL;
}
HILOG_INFO("test0002 listen success\n");
struct sockaddr_in client_addr;
memset(&client_addr, 0, sizeof(client_addr));
socklen_t len = sizeof(client_addr);
HILOG_INFO("test0002 waiting for client.......\n");
wflag = 1;
char str[1024];
while(wflag)
{
client_st = accept(st, (struct sockaddr*) &client_addr, &len);
if (client_st == -1)
{
HILOG_INFO("test0002 accept failed %s\n", strerror(errno));
return NULL;
}
HILOG_INFO("test0002 accept by %s\n", inet_ntoa(client_addr.sin_addr));
while (wflag)
{
memset(str, 0, sizeof(str));
int numbytes = recv(client_st, str, sizeof(str), 0);
if (numbytes <= 0)
break;
//if(wflag == 0) break;
strcpy(buf,str);
if((int)str[0] == 170)
{
int cPara1 = (int)str[1];
int cPara2 = (int)str[2];
int cPara3 = (int)str[3];
napi_create_object(envs, &jsObj); //创建JS回调函数对应的参数对象
napi_create_int32(envs, cPara1, &prop1);
napi_create_int32(envs, cPara2, &prop2);
napi_create_int32(envs, cPara3, &prop3);
napi_set_named_property(envs, jsObj, "prop1", prop1); //设置JS参数对象属性值
napi_set_named_property(envs, jsObj, "prop2", prop2);
napi_set_named_property(envs, jsObj, "prop3", prop3);
napi_call_function(envs, nullptr, callback, 1, &jsObj, &undefine); //使用生成的JS参数,调用对应的JS回调函数
}
buflen = strlen(str);
//send(client_st, str, strlen(str), 0);
}
}
return NULL;
}
//启动
static napi_value ServerStart(napi_env env, napi_callback_info info)
{
size_t argc = 1; //参数个数定义
napi_value argv[argc];
napi_value thisVar = nullptr;
void *data = nullptr;
envs = env;
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
NAPI_ASSERT(env, argc >= 1, "JSCallback Wrong number of arguments"); //参数个数校验
napi_valuetype callbackType = napi_undefined;
napi_typeof(env, argv[0], &callbackType);
NAPI_ASSERT(env, callbackType == napi_function, "parameter 1 type mismatch"); //参数类型校验,传进来的须是函数类型
napi_create_reference(env, argv[0], 1, &CallbackReff); //创建引用
//napi_get_reference_value(env, CallbackRef, &callback); //根据引用获取回调函数callback
pthread_t thrd;
HILOG_INFO("test0002 thrs start!");
//pthread_create(&thrd1, NULL, recvsocket, &client_st);
pthread_create(&thrd, NULL, socketserverthrd,NULL);
HILOG_INFO("test0002 end!");
napi_value result = nullptr;
napi_get_undefined(env, &result);
return result;
}
//停止
static napi_value ServerStop(napi_env env, napi_callback_info info)
{
close(st);
wflag = 0;
napi_value result = nullptr;
napi_get_undefined(env, &result);
return result;
}
//发送
static napi_value ServerWrite(napi_env env, napi_callback_info info)
{
size_t requireArgc = 3;
size_t argc = 3;
napi_value args[3] = { nullptr };
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
NAPI_ASSERT(env, argc >= requireArgc, "Wrong number of arguments");
napi_valuetype valuetype0;
NAPI_CALL(env, napi_typeof(env, args[0], &valuetype0));
napi_valuetype valuetype1;
NAPI_CALL(env, napi_typeof(env, args[1], &valuetype1));
napi_valuetype valuetype2;
NAPI_CALL(env, napi_typeof(env, args[2], &valuetype2));
NAPI_ASSERT(env, valuetype0 == napi_number && valuetype1 == napi_number && valuetype2 == napi_number, "Wrong argument type. Numbers expected.");
char str[4];
uint32_t a,b,c;
NAPI_CALL(env, napi_get_value_uint32(env, args[0], &a));
NAPI_CALL(env, napi_get_value_uint32(env, args[1], &b));
NAPI_CALL(env, napi_get_value_uint32(env, args[2], &c));
str[0] = (char)0xAA;
str[1] = (char)a;
str[2] = (char)b;
str[3] = (char)c;
if (-1 == write(client_st, str,4)){
HILOG_INFO("test0002 okok servertest error");
}
napi_value result = nullptr;
napi_get_undefined(env, &result);
return result;
}
EXTERN_C_START

static napi_value Init(napi_env env, napi_value exports)
{

napi_property_descriptor desc[] = {
DECLARE_NAPI_FUNCTION("ServerStart", ServerStart),
DECLARE_NAPI_FUNCTION("ServerStop", ServerStop),
DECLARE_NAPI_FUNCTION("ServerWrite", ServerWrite)
};
NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));

return exports;
}

EXTERN_C_END


static napi_module demoModule = {
.nm_version = 1,
.nm_flags = 0,
.nm_filename = nullptr,
.nm_register_func = Init,
.nm_modname = "socketserver",
.nm_priv = ((void*)0),
.reserved = { 0 },
};

extern "C" __attribute__((constructor)) void RegisterModule(void)
{
napi_module_register(&demoModule);
}

②.编译文件设置。

路径:\OpenHarmony\foundation\ace\napi\sample\native_module_socket_server\BUILD.gn。

import("//build/ohos.gni")
ohos_shared_library("socketserver") {
include_dirs = [
"//third_party/node/src",
"//foundation/ace/napi/interfaces/kits",
]
sources = [
"native_module_socket_server.cpp"
]
deps = [ "//foundation/ace/napi:ace_napi" ]
relative_install_dir = "module"
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
subsystem_name = "ace"
part_name = "napi"
}

③.加入编译。

路径:\OpenHarmony\foundation\ace\napi\BUILD.gn。

 找到这里

if (!build_ohos_ndk) {
group("napi_packages_test") {
testonly = true

deps = [
"sample/native_module_demo:demo",
"sample/native_module_netserver:netserver",
"sample/native_module_storage:storage",
"test/unittest:unittest",
"sample/native_module_led:led",
"sample/native_module_testdemo02:testdemo02",
"sample/native_module_netanddev:netanddev",
"sample/native_module_socket_server:socketserver" 《《《添加这个
]

if (is_standard_system) {
deps += [ "sample/native_module_ability:ability" ]
}
}

}

④.编译。

在源码根目录下运行。

./build.sh --product-name Hi3516DV300 --build-target make_test

⑤.编译输出路径。

路径:\OpenHarmony\out\hi3516dv300\ace\napi。

其中这个libsocketserver.z.so文件是我们要用的文件。

⑥.拷贝动态库到开发板。

电脑用数据线连接到开发板。

(1)两个打开CMD。

(2)连接开发板 (第一个CMD)。

hdc_std shell

(3)打开读写权限 (第一个CMD)。

mount -o remount,rw /

(4)发送动态库文件 (第二个CMD)。

hdc_std file send libsocketserver.z.so /system/lib/module/

(5)给动态库添加权限 (第一个CMD)。

chmod 666 /system/lib/module/libsocketserver.z.so

4、eTS APP代码实现部分

import socket from '@ohos.socketserver';
var homebuf; //设置全局变量,用来保存上下文
@Entry
@Component
struct Sockertest {
@State inSetValue: number = 0;
napicallback(data){ //socket server回调函数
homebuf.inSetValue = data.prop1;
console.log("test socketserver "+data.prop1+" "+data.prop2+" "+data.prop3+" "); //打印输出所有信息
}
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Text('test socketserver')
.fontSize(50)
.fontWeight(FontWeight.Bold)
Text(this.inSetValue.toFixed(0)).fontSize(72).width('18%')
}
.width('100%')
.height('100%')
}
onPageShow() { //生命周期
socket.ServerStart(this.napicallback); //打sockerServer
homebuf=this;
}
}

5、安装测试

①.eTS APP 安装效果图。

②.连接开发板的TCP server 并发送 AA 01 00 00 到开发板。

软件名:网络调试助手V4.2.1.exe。

命令解释:AA 01 00 00。

AA是命令头,01 00 00 是转发到eTS上的数据,本次实验在使用第一位 01 测试结果。

注:你们可以写更好的协议,以上的协议很烂是我随便写的(哈哈),因为是测试用的。

具体的你们看看我上面写的代码。

③ .查看开发板接收AA 01 00 00 效果。

④.发送 AA 06 00 00 到开发板。

⑤ .查看开发板接收AA 06 00 00 效果。

⑥.测试成功!!!

6、注意事项

①.本次实验要连接到网络。

②.eTS导入这个包报错不用管。

③.很多人不懂查看ip。

1.打开CMD
2.输入hdc_std shell
3.输入ifconfig

​想了解更多内容,请访问:​

​51CTO和华为官方合作共建的鸿蒙技术社区​

​https://ost.51cto.com​

来源:鸿蒙社区内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯