8

openharmony标准系统L2 JS、eTS 的napi socket 网络接口开发 TCP-OpenHarmony技术社区...

 2 years ago
source link: https://ost.51cto.com/posts/10974
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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);
   }

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK