未验证 提交 d46b77f6 编写于 作者: O openharmony_ci 提交者: Gitee

!20464 添加 vpn 的md文件

Merge pull request !20464 from 徐杰/feature_vpn
# VPN管理
## 简介
VPN即虚拟专网(VPN-Virtual Private Network)在公用网络上建立专用网络的技术。整个VPN网络的任意两个节点之间的连接并没有传统专网所需的端到端的物理链路,而是架构在公用网络服务商所提供的网络平台(如Internet)之上的逻辑网络,用户数据在逻辑链路中传输。
> **说明:**
> 为了保证应用的运行效率,大部分API调用都是异步的,对于异步调用的API均提供了callback和Promise两种方式,以下示例均采用callback函数,更多方式可以查阅[API参考](../reference/apis/js-apis-net-vpn.md)。
以下分别介绍具体开发方式。
## 接口说明
完整的JS API说明以及实例代码请参考:[VPN API参考](../reference/apis/js-apis-net-vpn.md)
| 类型 | 接口 | 功能说明 |
| ---- | ---- | ---- |
| ohos.net.vpn | setUp(config: VpnConfig, callback: AsyncCallback\<number\>): void | 建立一个VPN网络,使用callback方式作为异步方法。 |
| ohos.net.vpn | protect(socketFd: number, callback: AsyncCallback\<void\>): void | 保护VPN的隧道,使用callback方式作为异步方法。 |
| ohos.net.vpn | destroy(callback: AsyncCallback\<void\>): void | 销毁一个VPN网络,使用callback方式作为异步方法。 |
## 启动VPN的流程
1. 建立一个VPN的网络隧道,下面以UDP隧道为例。
2. 保护前一步建立的UDP隧道。
3. 建立一个VPN网络。
4. 处理虚拟网卡的数据,如:读写操作。
5. 销毁VPN网络。
本示例通过 Native C++ 的方式开发应用程序,Native C++ 可参考: [简易Native C++ 示例(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/NativeAPI/NativeTemplateDemo)
示例程序主要包含两个部分:js功能代码和C++功能代码
## VPN示例源码(js部分)
主要功能:实现业务逻辑,如:创建隧道、建立VPN网络、保护VPN网络、销毁VPN网络
```js
import hilog from '@ohos.hilog';
import vpn from '@ohos.net.vpn';
import UIAbility from '@ohos.app.ability.UIAbility';
import vpn_client from "libvpn_client.so"
class EntryAbility extends UIAbility {
onWindowStageCreate(windowStage) {
globalThis.context = this.context;
}
}
let TunnelFd = -1
let VpnConnection = vpn.createVpnConnection(globalThis.context)
@Entry
@Component
struct Index {
@State message: string = 'Test VPN'
//1. 建立一个VPN的网络隧道,下面以UDP隧道为例。
CreateTunnel() {
TunnelFd = vpn_client.udpConnect("192.168.43.208", 8888)
}
//2. 保护前一步建立的UDP隧道。
Protect() {
VpnConnection.protect(TunnelFd).then(function () {
console.info("vpn Protect Success.")
}).catch(function (err) {
console.info("vpn Protect Failed " + JSON.stringify(err))
})
}
SetupVpn() {
let config = {
addresses: [{
address: {
address: "10.0.0.5",
family: 1
},
prefixLength: 24,
}],
routes: [],
mtu: 1400,
dnsAddresses: [
"114.114.114.114"
],
acceptedApplications: [],
refusedApplications: []
}
try {
//3. 建立一个VPN网络。
VpnConnection.setUp(config, (error, data) => {
console.info("tunfd: " + JSON.stringify(data));
//4. 处理虚拟网卡的数据,如:读写操作。
vpn_client.startVpn(data, TunnelFd)
})
} catch (error) {
console.info("vpn setUp fail " + JSON.stringify(error));
}
}
//5.销毁VPN网络。
Destroy() {
vpn_client.stopVpn(TunnelFd)
VpnConnection.destroy().then(function () {
console.info("vpn Destroy Success.")
}).catch(function (err) {
console.info("vpn Destroy Failed " + JSON.stringify(err))
})
}
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
.onClick(() => {
console.info("vpn Client")
})
Button('CreateTunnel').onClick(() => {
this.CreateTunnel()
}).fontSize(50)
Button('Protect').onClick(() => {
this.Protect()
}).fontSize(50)
Button('SetupVpn').onClick(() => {
this.SetupVpn()
}).fontSize(50)
Button('Destroy').onClick(() => {
this.Destroy()
}).fontSize(50)
}
.width('100%')
}
.height('100%')
}
}
```
## VPN示例源码(c++部分)
主要功能:具体业务的底层实现,如:UDP隧道Client端的实现、虚拟网卡读写数据的实现
```c++
#include "napi/native_api.h"
#include "hilog/log.h"
#include <cstring>
#include <thread>
#include <js_native_api.h>
#include <js_native_api_types.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <thread>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define BUFFER_SIZE 2048
#define VPN_LOG_TAG "NetMgrVpn"
#define VPN_LOG_DOMAIN 0x15b0
#define MAKE_FILE_NAME (strrchr(__FILE__, '/') + 1)
#define NETMANAGER_VPN_LOGE(fmt, ...) \
OH_LOG_Print(LOG_APP, LOG_ERROR, VPN_LOG_DOMAIN, VPN_LOG_TAG, "vpn [%{public}s %{public}d] " fmt, MAKE_FILE_NAME, \
__LINE__, ##__VA_ARGS__)
#define NETMANAGER_VPN_LOGI(fmt, ...) \
OH_LOG_Print(LOG_APP, LOG_INFO, VPN_LOG_DOMAIN, VPN_LOG_TAG, "vpn [%{public}s %{public}d] " fmt, MAKE_FILE_NAME, \
__LINE__, ##__VA_ARGS__)
#define NETMANAGER_VPN_LOGD(fmt, ...) \
OH_LOG_Print(LOG_APP, LOG_DEBUG, VPN_LOG_DOMAIN, VPN_LOG_TAG, "vpn [%{public}s %{public}d] " fmt, MAKE_FILE_NAME, \
__LINE__, ##__VA_ARGS__)
struct FdInfo {
int32_t tunFd = 0;
int32_t tunnelFd = 0;
struct sockaddr_in serverAddr;
};
static FdInfo fdInfo;
static bool threadRunF = false;
static std::thread threadt1;
static std::thread threadt2;
//获取对应字符串数据, 用于获取udp server 的IP地址
static constexpr const int MAX_STRING_LENGTH = 1024;
std::string GetStringFromValueUtf8(napi_env env, napi_value value) {
std::string result;
char str[MAX_STRING_LENGTH] = {0};
size_t length = 0;
napi_get_value_string_utf8(env, value, str, MAX_STRING_LENGTH, &length);
if (length > 0) {
return result.append(str, length);
}
return result;
}
void HandleReadTunfd(FdInfo fdInfo) {
uint8_t buffer[BUFFER_SIZE] = {0};
while (threadRunF) {
int ret = read(fdInfo.tunFd, buffer, sizeof(buffer));
if (ret <= 0) {
if (errno != 11) {
NETMANAGER_VPN_LOGE("read tun device error: %{public}d, tunfd: %{public}d", errno, fdInfo.tunFd);
}
continue;
}
// 读取到虚拟网卡的数据,通过udp隧道,发送给服务器
NETMANAGER_VPN_LOGD("buffer: %{public}s, len: %{public}d", buffer, ret);
ret = sendto(fdInfo.tunnelFd, buffer, ret, 0, (struct sockaddr *)&fdInfo.serverAddr, sizeof(fdInfo.serverAddr));
if (ret <= 0) {
NETMANAGER_VPN_LOGE("send to server[%{public}s:%{public}d] failed, ret: %{public}d, error: %{public}s",
inet_ntoa(fdInfo.serverAddr.sin_addr), ntohs(fdInfo.serverAddr.sin_port), ret,
strerror(errno));
continue;
}
}
}
void HandleTcpReceived(FdInfo fdInfo) {
int addrlen = sizeof(struct sockaddr_in);
uint8_t buffer[BUFFER_SIZE] = {0};
while (threadRunF) {
int length = recvfrom(fdInfo.tunnelFd, buffer, sizeof(buffer), 0, (struct sockaddr *)&fdInfo.serverAddr,
(socklen_t *)&addrlen);
if (length < 0) {
if (errno != 11) {
NETMANAGER_VPN_LOGE("read tun device error: %{public}d,tunnelfd: %{public}d", errno, fdInfo.tunnelFd);
}
continue;
}
// 接收到udp server的数据,写入到虚拟网卡中
NETMANAGER_VPN_LOGD("from [%{public}s:%{public}d] data: %{public}s, len: %{public}d",
inet_ntoa(fdInfo.serverAddr.sin_addr), ntohs(fdInfo.serverAddr.sin_port), buffer, length);
int ret = write(fdInfo.tunFd, buffer, length);
if (ret <= 0) {
NETMANAGER_VPN_LOGE("error Write To Tunfd, errno: %{public}d", errno);
}
}
}
static napi_value UdpConnect(napi_env env, napi_callback_info info) {
size_t argc = 2;
napi_value args[2] = {nullptr};
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
int32_t port = 0;
napi_get_value_int32(env, args[1], &port);
std::string ipAddr = GetStringFromValueUtf8(env, args[0]);
NETMANAGER_VPN_LOGI("ip: %{public}s port: %{public}d", ipAddr.c_str(), port);
// 建立udp隧道
int32_t sockFd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockFd == -1) {
NETMANAGER_VPN_LOGE("socket() error");
return 0;
}
struct timeval timeout = {1, 0};
setsockopt(sockFd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(struct timeval));
memset(&fdInfo.serverAddr, 0, sizeof(fdInfo.serverAddr));
fdInfo.serverAddr.sin_family = AF_INET;
fdInfo.serverAddr.sin_addr.s_addr = inet_addr(ipAddr.c_str()); // server's IP addr
fdInfo.serverAddr.sin_port = htons(port); // port
NETMANAGER_VPN_LOGI("Connection successful");
napi_value tunnelFd;
napi_create_int32(env, sockFd, &tunnelFd);
return tunnelFd;
}
static napi_value StartVpn(napi_env env, napi_callback_info info) {
size_t argc = 2;
napi_value args[2] = {nullptr};
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
napi_get_value_int32(env, args[0], &fdInfo.tunFd);
napi_get_value_int32(env, args[1], &fdInfo.tunnelFd);
if (threadRunF) {
threadRunF = false;
threadt1.join();
threadt2.join();
}
// 启动两个线程, 一个处理读取虚拟网卡的数据,另一个接收服务端的数据
threadRunF = true;
std::thread tt1(HandleReadTunfd, fdInfo);
std::thread tt2(HandleTcpReceived, fdInfo);
threadt1 = std::move(tt1);
threadt2 = std::move(tt2);
NETMANAGER_VPN_LOGI("StartVpn successful");
napi_value retValue;
napi_create_int32(env, 0, &retValue);
return retValue;
}
static napi_value StopVpn(napi_env env, napi_callback_info info) {
size_t argc = 1;
napi_value args[1] = {nullptr};
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
int32_t tunnelFd;
napi_get_value_int32(env, args[0], &tunnelFd);
if (tunnelFd) {
close(tunnelFd);
tunnelFd = 0;
}
// 停止两个线程
if (threadRunF) {
threadRunF = false;
threadt1.join();
threadt2.join();
}
NETMANAGER_VPN_LOGI("StopVpn successful");
napi_value retValue;
napi_create_int32(env, 0, &retValue);
return retValue;
}
EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports) {
napi_property_descriptor desc[] = {
{"udpConnect", nullptr, UdpConnect, nullptr, nullptr, nullptr, napi_default, nullptr},
{"startVpn", nullptr, StartVpn, nullptr, nullptr, nullptr, napi_default, nullptr},
{"stopVpn", nullptr, StopVpn, nullptr, nullptr, nullptr, napi_default, nullptr},
};
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 = "entry",
.nm_priv = ((void *)0),
.reserved = {0},
};
extern "C" __attribute__((constructor)) void RegisterEntryModule(void) {
napi_module_register(&demoModule);
}
```
# @ohos.net.vpn (VPN管理)
VPN管理模块,支持VPN的启动和停止功能。
> **说明:**
> 本模块首批接口从API version 10开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。
## 导入模块
```js
import vpn from '@ohos.net.vpn';
```
## vpn.createVpnConnection
createVpnConnection(context: AbilityContext): VpnConnection
创建一个VPN连接对象。
**系统能力**:SystemCapability.Communication.NetManager.Vpn
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| ------------ | ----------------------------- | ---- | ------------------------------------------------------------ |
| context | [AbilityContext](js-apis-inner-application-uiAbilityContext.md#uiabilitycontext) | 是 | 指定context |
**返回值:**
| 类型 | 说明 |
| :--------------------------------- | :---------------------- |
| [VpnConnection](#vpnconnection) | 返回一个VPN连接对象。 |
**错误码:**
以下错误码的详细介绍参见[VPN错误码](../errorcodes/errorcode-net-vpn.md)
| 错误码ID | 错误信息 |
| ------- | ----------------------------- |
| 401 | Parameter error. |
**示例:**
Stage模型示例:
```ts
// 获取context
import UIAbility from '@ohos.app.ability.UIAbility';
class EntryAbility extends UIAbility {
onWindowStageCreate(windowStage){
globalThis.context = this.context;
}
}
let context = globalThis.context;
VpnConnection = vpn.createVpnConnection(context);
console.info("vpn onInit: " + JSON.stringify(VpnConnection));
```
## VpnConnection
VPN连接对象。在调用VpnConnection的方法前,需要先通过[vpn.createVpnConnection](#vpncreatevpnconnection)创建VPN连接对象。
### setUp
setUp(config: VpnConfig, callback: AsyncCallback\<number\>): void
使用config创建一个vpn网络,使用callback方式作为异步方法。
**系统接口**:此接口为系统接口。
**需要权限**:ohos.permission.MANAGE_VPN
**系统能力**:SystemCapability.Communication.NetManager.Vpn
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| ------------ | ----------------------------- | ---- | ------------------------------------------------------------ |
| config | [VpnConfig](#vpnconfig) | 是 | 指定VPN网络的配置信息。 |
| callback | AsyncCallback\<number\> | 是 | 回调函数,当成功启动VPN网络时,返回虚拟网卡的文件描述符fd, error为undefined,否则为错误对象。 |
**错误码:**
以下错误码的详细介绍参见[VPN错误码](../errorcodes/errorcode-net-vpn.md)
| 错误码ID | 错误信息 |
| ------- | ----------------------------- |
| 201 | Permission denied. |
| 202 | Non-system applications use system APIs. |
| 401 | Parameter error. |
| 2200001 | Invalid parameter value. |
| 2200002 | Operation failed. Cannot connect to service. |
| 2100003 | System internal error. |
| 2203001 | VPN creation denied, please check the user type. |
| 2203002 | VPN exist already, please execute destroy first. |
**示例:**
```js
let config = {
addresses: [{
address: {
address: "10.0.0.5",
family: 1
},
prefixLength: 24,
}],
routes: [],
mtu: 1400,
dnsAddresses:[
"114.114.114.114"
],
trustedApplications:[],
blockedApplications:[]
}
VpnConnection.setUp(config, (error, data) => {
console.info(JSON.stringify(error));
console.info("tunfd: " + JSON.stringify(data));
})
```
### setUp
setUp(config: VpnConfig): Promise\<number\>
使用config创建一个vpn网络,使用Promise方式作为异步方法。
**系统接口**:此接口为系统接口。
**需要权限**:ohos.permission.MANAGE_VPN
**系统能力**:SystemCapability.Communication.NetManager.Vpn
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| ------------ | ----------------------------- | ---- | ------------------------------------------------------------ |
| config | [VpnConfig](#vpnconfig) | 是 | 指定VPN网络的配置信息。 |
**返回值:**
| 类型 | 说明 |
| --------------------------------- | ------------------------------------- |
| Promise\<number\> | 以Promise形式返回获取结果,返回指定虚拟网卡的文件描述符fd。 |
**错误码:**
以下错误码的详细介绍参见[VPN错误码](../errorcodes/errorcode-net-vpn.md)
| 错误码ID | 错误信息 |
| ------- | ----------------------------- |
| 201 | Permission denied. |
| 202 | Non-system applications use system APIs. |
| 401 | Parameter error. |
| 2200001 | Invalid parameter value. |
| 2200002 | Operation failed. Cannot connect to service. |
| 2100003 | System internal error. |
| 2203001 | VPN creation denied, please check the user type. |
| 2203002 | VPN exist already, please execute destroy first. |
**示例:**
```js
let config = {
addresses: [{
address: {
address: "10.0.0.5",
family: 1
},
prefixLength: 24,
}],
routes: [],
mtu: 1400,
dnsAddresses:[
"114.114.114.114"
],
trustedApplications:[],
blockedApplications:[]
}
VpnConnection.setUp(config).then((data) => {
console.info(TAG + "setUp success, tunfd: " + JSON.stringify(data))
}).catch(err => {
console.info(TAG + "setUp fail" + JSON.stringify(err))
})
```
### protect
protect(socketFd: number, callback: AsyncCallback\<void\>): void
保护套接字不受VPN连接影响,通过该套接字发送的数据将直接基于物理网络收发,因此其流量不会通过VPN转发,使用callback方式作为异步方法。
**系统接口**:此接口为系统接口。
**需要权限**:ohos.permission.MANAGE_VPN
**系统能力**:SystemCapability.Communication.NetManager.Vpn
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| ------------ | ----------------------------- | ---- | ------------------------------------------------------------ |
| socketFd | number | 是 | 指定保护的socketfd, 该文件描述符通过[getSocketFd](js-apis-socket.md#getsocketfd10)获取。 |
| callback | AsyncCallback\<void\> | 是 | 回调函数,成功时,error为undefined,失败返回错误码错误信息。 |
**错误码:**
以下错误码的详细介绍参见[VPN错误码](../errorcodes/errorcode-net-vpn.md)
| 错误码ID | 错误信息 |
| ------- | ----------------------------- |
| 201 | Permission denied. |
| 202 | Non-system applications use system APIs. |
| 401 | Parameter error. |
| 2200001 | Invalid parameter value. |
| 2200002 | Operation failed. Cannot connect to service. |
| 2100003 | System internal error. |
| 2203004 | Invalid socket file descriptor. |
**示例:**
```js
import socket from "@ohos.net.socket";
var tcp = socket.constructTCPSocketInstance();
tcp.bind({
address: "0.0.0.0",
family: 1
})
let connectAddress = {
address: "192.168.1.11",
port: 8888,
family: 1
};
tcp.connect({
address: connectAddress, timeout: 6000
})
tcp.getSocketFd().then((tunnelfd) => {
console.info("tunenlfd: " + tunnelfd);
VpnConnection.protect(tunnelfd, (error) => {
console.info(JSON.stringify(error));
})
})
```
### protect
protect(socketFd: number): Promise\<void\>
保护套接字不受VPN连接影响,通过该套接字发送的数据将直接基于物理网络收发,因此其流量不会通过VPN转发, 使用Promise方式作为异步方法。
**系统接口**:此接口为系统接口。
**需要权限**:ohos.permission.MANAGE_VPN
**系统能力**:SystemCapability.Communication.NetManager.Vpn
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| ------------ | ----------------------------- | ---- | ------------------------------------------------------------ |
| socketFd | number | 是 | 指定保护的socketfd, 该文件描述符通过[getSocketFd](js-apis-socket.md#getsocketfd10-1)获取。 |
**返回值:**
| 类型 | 说明 |
| --------------------------------- | ------------------------------------- |
| Promise\<void\> | 以Promise形式返回设定结果,失败返回错误码错误信息。 |
**错误码:**
以下错误码的详细介绍参见[VPN错误码](../errorcodes/errorcode-net-vpn.md)
| 错误码ID | 错误信息 |
| ------- | ----------------------------- |
| 201 | Permission denied. |
| 202 | Non-system applications use system APIs. |
| 401 | Parameter error. |
| 2200001 | Invalid parameter value. |
| 2200002 | Operation failed. Cannot connect to service. |
| 2100003 | System internal error. |
| 2203004 | Invalid socket file descriptor. |
**示例:**
```js
import socket from "@ohos.net.socket";
var tcp = socket.constructTCPSocketInstance();
tcp.bind({
address: "0.0.0.0",
family: 1
})
let connectAddress = {
address: "192.168.1.11",
port: 8888,
family: 1
};
tcp.connect({
address: connectAddress, timeout: 6000
})
tcp.getSocketFd().then((tunnelfd) => {
console.info("tunenlfd: " + tunnelfd);
VpnConnection.protect(tunnelfd).then(() => {
console.info("protect success.")
}).catch(err => {
console.info("protect fail" + JSON.stringify(err))
})
})
```
### destroy
destroy(callback: AsyncCallback\<void\>): void
销毁启动的VPN网络,使用callback方式作为异步方法。
**系统接口**:此接口为系统接口。
**需要权限**:ohos.permission.MANAGE_VPN
**系统能力**:SystemCapability.Communication.NetManager.Vpn
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| ------------ | ----------------------------- | ---- | ------------------------------------------------------------ |
| callback | AsyncCallback\<void\> | 是 | 回调函数,成功时,error为undefined,失败返回错误码错误信息。 |
**错误码:**
以下错误码的详细介绍参见[VPN错误码](../errorcodes/errorcode-net-vpn.md)
| 错误码ID | 错误信息 |
| ------- | ----------------------------- |
| 201 | Permission denied. |
| 202 | Non-system applications use system APIs. |
| 401 | Parameter error. |
| 2200002 | Operation failed. Cannot connect to service. |
| 2100003 | System internal error. |
**示例:**
```js
VpnConnection.destroy((error) => {
console.info(JSON.stringify(error));
})
```
### destroy
destroy(): Promise\<void\>
销毁启动的VPN网络,使用Promise方式作为异步方法。
**系统接口**:此接口为系统接口。
**需要权限**:ohos.permission.MANAGE_VPN
**系统能力**:SystemCapability.Communication.NetManager.Vpn
**返回值:**
| 类型 | 说明 |
| --------------------------------- | ------------------------------------- |
| Promise\<void\> | 以Promise形式返回设定结果,失败返回错误码错误信息。 |
**错误码:**
以下错误码的详细介绍参见[VPN错误码](../errorcodes/errorcode-net-vpn.md)
| 错误码ID | 错误信息 |
| ------- | ----------------------------- |
| 201 | Permission denied. |
| 202 | Non-system applications use system APIs. |
| 2200002 | Operation failed. Cannot connect to service. |
| 2100003 | System internal error. |
**示例:**
```js
VpnConnection.destroy().then(() => {
console.info("destroy success.")
}).catch(err => {
console.info("destroy fail" + JSON.stringify(err))
});
```
## VpnConfig
VPN配置参数。
**系统接口**:此接口为系统接口。
**系统能力**:SystemCapability.Communication.NetManager.Vpn
| 名称 | 类型 | 必填 | 说明 |
| ------- | ------ | -- |------------------------------ |
| addresses | Array\<[LinkAddress](js-apis-net-connection.md#linkaddress8)\> | 是 | VPN虚拟网卡的IP地址。 |
| routes | Array\<[RouteInfo](js-apis-net-connection.md#routeinfo8)\> | 否 | VPN虚拟网卡的路由信息。 |
| dnsAddresses | Array\<string\> | 否 | DNS服务器地址信息。 |
| searchDomains | Array\<string\> | 否 | DNS的搜索域列表。 |
| mtu | number | 否 | 最大传输单元MTU值(单位:字节)。 |
| isIPv4Accepted | boolean | 否 | 是否支持IPV4, 默认值为true。 |
| isIPv6Accepted | boolean | 否 | 是否支持IPV6, 默认值为flase。 ||
| isLegacy | boolean | 否 | 是否支持内置VPN, 默认值为flase。 |
| isBlocking | boolean | 否 | 是否阻塞模式, 默认值为flase。 |
| trustedApplications | Array\<string\> | 否 | 白名单信息, string类型表示的包名。 |
| blockedApplications | Array\<string\> | 否 | 黑名单信息, string类型表示的包名。 |
......@@ -1235,6 +1235,87 @@ promise.then(() => {
});
```
### getSocketFd<sup>10+</sup>
getSocketFd(callback: AsyncCallback\<number\>): void
获取TCPSocket的文件描述符。使用callback方式作为异步方法。
> **说明:**
> bind或connect方法调用成功后,才可调用此方法。
**系统能力**:SystemCapability.Communication.NetStack
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| -------- | ------------------------------------------------------ | ---- | ---------- |
| callback | AsyncCallback\<number\> | 是 | 回调函数,当成功时,返回socket的文件描述符,失败时,返回undefined。 |
**示例:**
```js
import socket from "@ohos.net.socket";
var tcp = socket.constructTCPSocketInstance();
let tunnelfd = 0
tcp.bind({
address: "0.0.0.0",
family: 1,
})
let connectAddress = {
address: "192.168.1.11",
port: 8888,
family: 1
};
tcp.connect({
address: connectAddress, timeout: 6000
})
tcp.getSocketFd((data) => {
console.info("tunenlfd: " + data);
tunnelfd = data
})
```
### getSocketFd<sup>10+</sup>
getSocketFd(): Promise\<number\>
获取TCPSocket的文件描述符。使用Promise方式作为异步方法。
> **说明:**
> bind或connect方法调用成功后,才可调用此方法。
**系统能力**:SystemCapability.Communication.NetStack
**返回值:**
| 类型 | 说明 |
| :----------------------------------------------- | :----------------------------------------- |
| Promise\<number\> | 以Promise形式返回socket的文件描述符。 |
**示例:**
```js
import socket from "@ohos.net.socket";
var tcp = socket.constructTCPSocketInstance();
let tunnelfd = 0
tcp.bind({
address: "0.0.0.0",
family: 1,
})
let connectAddress = {
address: "192.168.1.11",
port: 8888,
family: 1
};
tcp.connect({
address: connectAddress, timeout: 6000
})
tcp.getSocketFd().then((data) => {
console.info("tunenlfd: " + data);
tunnelfd = data
})
```
### setExtraOptions<sup>7+</sup>
setExtraOptions(options: TCPExtraOptions, callback: AsyncCallback\<void\>): void
......
# VPN错误码
> **说明:**
>
> 以下仅介绍本模块特有错误码,通用错误码请参考[通用错误码说明文档](errorcode-universal.md)。
## 2203001 VPN创建失败
**错误信息**
VPN creation denied, please check the user type.
**错误描述**
拒绝创建VPN,请检测当前用户的类型。
**可能原因**
登录系统的用户类型不匹配, GUEST用户不能调用setUp接口。
**处理步骤**
检查当前登录系统用户的类型。
## 2203002 VPN已存在
**错误信息**
VPN exist already, please execute destroy first.
**错误描述**
VPN连接已存在,请先调用destroy接口销毁VPN连接。
**可能原因**
VPN已经被创建。
**处理步骤**
先执行destory接口,再调用该接口。
## 2203004 无效描述符
**错误信息**
Invalid socket file descriptor.
**错误描述**
无效的文件描述符。
**可能原因**
tcp链路建立失败。
**处理步骤**
检查socket链路是否建立成功。
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册