天天看點

openharmony标準系統L2 JS、eTS 的napi socket 網絡接口開發 TCPopenharmony标準系統JS、eTS 的napi socket網絡接口開發 TCP

openharmony标準系統JS、eTS 的napi socket網絡接口開發 TCP

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标準系統網絡程式設計整體構思

openharmony标準系統L2 JS、eTS 的napi socket 網絡接口開發 TCPopenharmony标準系統JS、eTS 的napi socket網絡接口開發 TCP
①.本Demo簡單的建立一個簡單的socket server TCP
②.通過C 實作 4個NAPI接口
  • 啟動socket server 接口
  • 發送資料接口
  • 接收資料接口 (使用NAPI回調函數實作)
  • 關閉socket server 接口
③設定一個簡單的eTS APP使用NAPI網絡接口

3.napi代碼實作部分

①.代碼部分

路徑:\OpenHarmony\foundation\ace\napi\sample\native_module_socket_server\native_module_socket_server.cpp

注意:native_module_socket_server檔案夾自行建立

  • /*
    
     * Copyright (c) 2021 Huawei Device Co., Ltd.
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
       *
     * http://www.apache.org/licenses/LICENSE-2.0
        *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
       */
    #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
    /*
    
     * function for module exports
       */
       static napi_value Init(napi_env env, napi_value exports)
       {
       /*
    
        * Properties define
          */
          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
    
    /*
    
     * Module define
       */
       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 },
       };
       /*
     * Module register function
       */
       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/
           
openharmony标準系統L2 JS、eTS 的napi socket 網絡接口開發 TCPopenharmony标準系統JS、eTS 的napi socket網絡接口開發 TCP
5).給動态庫添權重限 (第一個CMD)
chmod 666 /system/lib/module/libsocketserver.z.so
           
openharmony标準系統L2 JS、eTS 的napi socket 網絡接口開發 TCPopenharmony标準系統JS、eTS 的napi socket網絡接口開發 TCP

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 安裝效果圖

openharmony标準系統L2 JS、eTS 的napi socket 網絡接口開發 TCPopenharmony标準系統JS、eTS 的napi socket網絡接口開發 TCP

②.連接配接開發闆的TCP server 并發送 AA 01 00 00 到開發闆

軟體名:網絡調試助手V4.2.1.exe

指令解釋:AA 01 00 00

AA是指令頭,01 00 00 是轉發到eTS上的資料,本次實驗在使用第一位 01 測試結果

注:你們可以寫更好的協定,以上的協定很爛是我随便寫的(哈哈),因為是測試用的

具體的你們看看我上面寫的代碼

openharmony标準系統L2 JS、eTS 的napi socket 網絡接口開發 TCPopenharmony标準系統JS、eTS 的napi socket網絡接口開發 TCP

③ .檢視開發闆接收AA 01 00 00 效果

openharmony标準系統L2 JS、eTS 的napi socket 網絡接口開發 TCPopenharmony标準系統JS、eTS 的napi socket網絡接口開發 TCP

④.發送 AA 06 00 00 到開發闆

openharmony标準系統L2 JS、eTS 的napi socket 網絡接口開發 TCPopenharmony标準系統JS、eTS 的napi socket網絡接口開發 TCP

⑤ .檢視開發闆接收AA 06 00 00 效果

openharmony标準系統L2 JS、eTS 的napi socket 網絡接口開發 TCPopenharmony标準系統JS、eTS 的napi socket網絡接口開發 TCP

⑥.測試成功!!!

6.注意事項

①.本次實驗要連接配接到網絡

②.eTS導入這個包報錯不用管

openharmony标準系統L2 JS、eTS 的napi socket 網絡接口開發 TCPopenharmony标準系統JS、eTS 的napi socket網絡接口開發 TCP

③.很多人不懂檢視ip

1.打開CMD

2.輸入hdc_std shell

3.輸入ifconfig
           

想了解更多關于鴻蒙的内容,請通路:

51CTO和華為官方合作共建的鴻蒙技術社群

https://ost.51cto.com/#bkwz

繼續閱讀