From 8c535e8eb839cf2bc1312173beeb83e030739797 Mon Sep 17 00:00:00 2001 From: guoyiming Date: Wed, 17 Aug 2022 06:18:34 +0000 Subject: [PATCH] =?UTF-8?q?Description:=20=E6=B7=BB=E5=8A=A0tcp=20sever?= =?UTF-8?q?=E7=9A=84=E6=8E=A5=E5=8F=A3listen=20Feature=20or=20Bugfix:=20Fe?= =?UTF-8?q?ature=20Binary=20Source:=20No?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: guoyiming --- frameworks/js/napi/BUILD.gn | 1 + .../include/tcp_listen_context.h | 40 ++++++++++ .../async_context/src/tcp_listen_context.cpp | 54 +++++++++++++ .../async_context/src/tcp_send_context.cpp | 6 ++ .../async_work/include/socket_async_work.h | 4 + .../async_work/src/socket_async_work.cpp | 10 +++ .../socket/constant/include/context_key.h | 2 + .../options/include/socket_remote_info.h | 6 ++ .../socket/options/include/tcp_send_options.h | 6 ++ .../socket/options/src/socket_remote_info.cpp | 10 +++ .../socket/options/src/tcp_send_options.cpp | 10 +++ .../socket/socket_exec/include/socket_exec.h | 5 ++ .../socket/socket_exec/src/socket_exec.cpp | 77 +++++++++++++++---- .../socket_module/include/socket_module.h | 2 + .../socket_module/src/socket_module.cpp | 7 ++ .../socket/task_queue/include/task_queue.h | 1 + interfaces/kits/js/@ohos.net.socket.d.ts | 15 ++++ 17 files changed, 243 insertions(+), 13 deletions(-) create mode 100755 frameworks/js/napi/socket/async_context/include/tcp_listen_context.h create mode 100755 frameworks/js/napi/socket/async_context/src/tcp_listen_context.cpp diff --git a/frameworks/js/napi/BUILD.gn b/frameworks/js/napi/BUILD.gn index 068914295..45650f074 100644 --- a/frameworks/js/napi/BUILD.gn +++ b/frameworks/js/napi/BUILD.gn @@ -132,6 +132,7 @@ ohos_shared_library("socket") { "socket/async_context/src/common_context.cpp", "socket/async_context/src/connect_context.cpp", "socket/async_context/src/tcp_extra_context.cpp", + "socket/async_context/src/tcp_listen_context.cpp", "socket/async_context/src/tcp_send_context.cpp", "socket/async_context/src/udp_extra_context.cpp", "socket/async_context/src/udp_send_context.cpp", diff --git a/frameworks/js/napi/socket/async_context/include/tcp_listen_context.h b/frameworks/js/napi/socket/async_context/include/tcp_listen_context.h new file mode 100755 index 000000000..58d03b888 --- /dev/null +++ b/frameworks/js/napi/socket/async_context/include/tcp_listen_context.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2021-2022 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. + */ + +#ifndef COMMUNICATIONNETSTACK_TCP_LISTEN_CONTEXT_H +#define COMMUNICATIONNETSTACK_TCP_LISTEN_CONTEXT_H + +#include "netstack_base_context.h" +#include "nocopyable.h" + +namespace OHOS::NetStack { +class TcpListenContext final : public BaseContext { +public: + DISALLOW_COPY_AND_MOVE(TcpListenContext); + + TcpListenContext() = delete; + + explicit TcpListenContext(napi_env env, EventManager *manager); + + void ParseParams(napi_value *params, size_t paramsCount); + + [[nodiscard]] int GetSocketFd() const; + +private: + bool CheckParamsType(napi_value *params, size_t paramsCount); +}; +} // namespace OHOS::NetStack + +#endif /* COMMUNICATIONNETSTACK_TCP_LISTEN_CONTEXT_H */ diff --git a/frameworks/js/napi/socket/async_context/src/tcp_listen_context.cpp b/frameworks/js/napi/socket/async_context/src/tcp_listen_context.cpp new file mode 100755 index 000000000..3b36a803d --- /dev/null +++ b/frameworks/js/napi/socket/async_context/src/tcp_listen_context.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2021-2022 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 "tcp_listen_context.h" + +#include "context_key.h" +#include "netstack_napi_utils.h" + +namespace OHOS::NetStack { +TcpListenContext::TcpListenContext(napi_env env, EventManager *manager) : BaseContext(env, manager) {} + +void TcpListenContext::ParseParams(napi_value *params, size_t paramsCount) +{ + bool valid = CheckParamsType(params, paramsCount); + if (!valid) { + return; + } + + if (paramsCount != PARAM_NONE) { + SetParseOK(SetCallback(params[0]) == napi_ok); + return; + } + SetParseOK(true); +} + +int TcpListenContext::GetSocketFd() const +{ + return (int)(uint64_t)manager_->GetData(); +} + +bool TcpListenContext::CheckParamsType(napi_value *params, size_t paramsCount) +{ + if (paramsCount == PARAM_NONE) { + return true; + } + + if (paramsCount == PARAM_JUST_CALLBACK) { + return NapiUtils::GetValueType(GetEnv(), params[0]) == napi_function; + } + return false; +} +} // namespace OHOS::NetStack diff --git a/frameworks/js/napi/socket/async_context/src/tcp_send_context.cpp b/frameworks/js/napi/socket/async_context/src/tcp_send_context.cpp index 90def4ba6..0346aa132 100644 --- a/frameworks/js/napi/socket/async_context/src/tcp_send_context.cpp +++ b/frameworks/js/napi/socket/async_context/src/tcp_send_context.cpp @@ -34,6 +34,12 @@ void TcpSendContext::ParseParams(napi_value *params, size_t paramsCount) std::string encoding = NapiUtils::GetStringPropertyUtf8(GetEnv(), params[0], KEY_ENCODING); options.SetEncoding(encoding); } + if (NapiUtils::HasNamedProperty(GetEnv(), params[0], KEY_CONNFD)) { + int32_t connfd = NapiUtils::GetUint32Property(GetEnv(), params[0], KEY_CONNFD); + options.SetConnfd(connfd); + } else { + options.SetConnfd(0); + } if (!GetData(params[0])) { return; } diff --git a/frameworks/js/napi/socket/async_work/include/socket_async_work.h b/frameworks/js/napi/socket/async_work/include/socket_async_work.h index 963b66677..f588825af 100644 --- a/frameworks/js/napi/socket/async_work/include/socket_async_work.h +++ b/frameworks/js/napi/socket/async_work/include/socket_async_work.h @@ -33,6 +33,8 @@ public: static void ExecConnect(napi_env env, void *data); + static void ExecTcpListen(napi_env env, void *data); + static void ExecTcpSend(napi_env env, void *data); static void ExecClose(napi_env env, void *data); @@ -52,6 +54,8 @@ public: static void ConnectCallback(napi_env env, napi_status status, void *data); + static void TcpListenCallback(napi_env env, napi_status status, void *data); + static void TcpSendCallback(napi_env env, napi_status status, void *data); static void CloseCallback(napi_env env, napi_status status, void *data); diff --git a/frameworks/js/napi/socket/async_work/src/socket_async_work.cpp b/frameworks/js/napi/socket/async_work/src/socket_async_work.cpp index f4a75cac4..5e5c7534d 100644 --- a/frameworks/js/napi/socket/async_work/src/socket_async_work.cpp +++ b/frameworks/js/napi/socket/async_work/src/socket_async_work.cpp @@ -51,6 +51,11 @@ void SocketAsyncWork::ExecClose(napi_env env, void *data) BaseAsyncWork::ExecAsyncWork(env, data); } +void SocketAsyncWork::ExecTcpListen(napi_env env, void *data) +{ + BaseAsyncWork::ExecAsyncWork(env, data); +} + void SocketAsyncWork::ExecTcpSend(napi_env env, void *data) { BaseAsyncWork::ExecAsyncWork(env, data); @@ -91,6 +96,11 @@ void SocketAsyncWork::ConnectCallback(napi_env env, napi_status status, void *da BaseAsyncWork::AsyncWorkCallback(env, status, data); } +void SocketAsyncWork::TcpListenCallback(napi_env env, napi_status status, void *data) +{ + BaseAsyncWork::AsyncWorkCallback(env, status, data); +} + void SocketAsyncWork::TcpSendCallback(napi_env env, napi_status status, void *data) { BaseAsyncWork::AsyncWorkCallback(env, status, data); diff --git a/frameworks/js/napi/socket/constant/include/context_key.h b/frameworks/js/napi/socket/constant/include/context_key.h index 404494829..9ac6c2cc7 100644 --- a/frameworks/js/napi/socket/constant/include/context_key.h +++ b/frameworks/js/napi/socket/constant/include/context_key.h @@ -22,6 +22,8 @@ #define KEY_PORT "port" +#define KEY_CONNFD "connfd" + #define KEY_TIMEOUT "timeout" #define KEY_ENCODING "encoding" diff --git a/frameworks/js/napi/socket/options/include/socket_remote_info.h b/frameworks/js/napi/socket/options/include/socket_remote_info.h index d5a5c7596..5882a0a12 100644 --- a/frameworks/js/napi/socket/options/include/socket_remote_info.h +++ b/frameworks/js/napi/socket/options/include/socket_remote_info.h @@ -36,6 +36,8 @@ public: void SetPort(uint16_t port); + void SetConnfd(int32_t connfd); + void SetSize(uint32_t size); [[nodiscard]] const std::string &GetAddress() const; @@ -44,6 +46,8 @@ public: [[nodiscard]] uint16_t GetPort() const; + [[nodiscard]] int32_t GetConnfd() const; + [[nodiscard]] uint32_t GetSize() const; private: @@ -53,6 +57,8 @@ private: uint16_t port_; + int32_t connfd_; + uint32_t size_; }; } // namespace OHOS::NetStack diff --git a/frameworks/js/napi/socket/options/include/tcp_send_options.h b/frameworks/js/napi/socket/options/include/tcp_send_options.h index 85db2ac36..87af02c1e 100644 --- a/frameworks/js/napi/socket/options/include/tcp_send_options.h +++ b/frameworks/js/napi/socket/options/include/tcp_send_options.h @@ -32,14 +32,20 @@ public: void SetEncoding(const std::string &encoding); + void SetConnfd(int32_t connfd); + [[nodiscard]] const std::string &GetData() const; [[nodiscard]] const std::string &GetEncoding() const; + [[nodiscard]] int32_t GetConnfd() const; + private: std::string data_; std::string encoding_; + + int32_t connfd_; }; } // namespace OHOS::NetStack diff --git a/frameworks/js/napi/socket/options/src/socket_remote_info.cpp b/frameworks/js/napi/socket/options/src/socket_remote_info.cpp index 0a0b6ab15..0a79c1d8c 100644 --- a/frameworks/js/napi/socket/options/src/socket_remote_info.cpp +++ b/frameworks/js/napi/socket/options/src/socket_remote_info.cpp @@ -42,6 +42,11 @@ void SocketRemoteInfo::SetPort(uint16_t port) port_ = port; } +void SocketRemoteInfo::SetConnfd(int32_t connfd) +{ + connfd_ = connfd; +} + void SocketRemoteInfo::SetSize(uint32_t size) { size_ = size; @@ -62,6 +67,11 @@ uint16_t SocketRemoteInfo::GetPort() const return port_; } +int32_t SocketRemoteInfo::GetConnfd() const +{ + return connfd_; +} + uint32_t SocketRemoteInfo::GetSize() const { return size_; diff --git a/frameworks/js/napi/socket/options/src/tcp_send_options.cpp b/frameworks/js/napi/socket/options/src/tcp_send_options.cpp index b2cea231c..edf90cb56 100644 --- a/frameworks/js/napi/socket/options/src/tcp_send_options.cpp +++ b/frameworks/js/napi/socket/options/src/tcp_send_options.cpp @@ -31,6 +31,11 @@ void TCPSendOptions::SetEncoding(const std::string &encoding) encoding_ = encoding; } +void TCPSendOptions::SetConnfd(int32_t connfd) +{ + connfd_ = connfd; +} + const std::string &TCPSendOptions::GetData() const { return data_; @@ -40,4 +45,9 @@ const std::string &TCPSendOptions::GetEncoding() const { return encoding_; } + +int32_t TCPSendOptions::GetConnfd() const +{ + return connfd_; +} } // namespace OHOS::NetStack \ No newline at end of file diff --git a/frameworks/js/napi/socket/socket_exec/include/socket_exec.h b/frameworks/js/napi/socket/socket_exec/include/socket_exec.h index 0100761e1..038c40d00 100644 --- a/frameworks/js/napi/socket/socket_exec/include/socket_exec.h +++ b/frameworks/js/napi/socket/socket_exec/include/socket_exec.h @@ -20,6 +20,7 @@ #include "common_context.h" #include "connect_context.h" #include "tcp_extra_context.h" +#include "tcp_listen_context.h" #include "tcp_send_context.h" #include "udp_extra_context.h" #include "udp_send_context.h" @@ -40,6 +41,8 @@ bool ExecConnect(ConnectContext *context); bool ExecTcpSend(TcpSendContext *context); +bool ExecTcpListen(TcpListenContext *context); + bool ExecClose(CloseContext *context); bool ExecGetState(GetStateContext *context); @@ -57,6 +60,8 @@ napi_value UdpSendCallback(UdpSendContext *context); napi_value ConnectCallback(ConnectContext *context); +napi_value TcpListenCallback(TcpListenContext *context); + napi_value TcpSendCallback(TcpSendContext *context); napi_value CloseCallback(CloseContext *context); diff --git a/frameworks/js/napi/socket/socket_exec/src/socket_exec.cpp b/frameworks/js/napi/socket/socket_exec/src/socket_exec.cpp index 6758150ff..327e3e1b3 100644 --- a/frameworks/js/napi/socket/socket_exec/src/socket_exec.cpp +++ b/frameworks/js/napi/socket/socket_exec/src/socket_exec.cpp @@ -39,6 +39,8 @@ static constexpr const int ADDRESS_INVALID = -1; static constexpr const int NO_MEMORY = -2; +static constexpr const int BACK_LOG = 128; // how many pending connections queue will hold + namespace OHOS::NetStack::SocketExec { struct MessageData { MessageData() = delete; @@ -143,6 +145,7 @@ static napi_value MakeJsMessageParam(napi_env env, napi_value msgBuffer, SocketR NapiUtils::SetStringPropertyUtf8(env, jsRemoteInfo, KEY_ADDRESS, remoteInfo->GetAddress()); NapiUtils::SetStringPropertyUtf8(env, jsRemoteInfo, KEY_FAMILY, remoteInfo->GetFamily()); NapiUtils::SetUint32Property(env, jsRemoteInfo, KEY_PORT, remoteInfo->GetPort()); + NapiUtils::SetInt32Property(env, jsRemoteInfo, KEY_CONNFD, remoteInfo->GetConnfd()); NapiUtils::SetUint32Property(env, jsRemoteInfo, KEY_SIZE, remoteInfo->GetSize()); NapiUtils::SetNamedProperty(env, obj, KEY_REMOTE_INFO, jsRemoteInfo); @@ -174,7 +177,7 @@ static napi_value MakeMessage(napi_env env, void *para) return MakeJsMessageParam(env, msgBuffer, &messageData->remoteInfo); } -static void OnRecvMessage(EventManager *manager, void *data, size_t len, sockaddr *addr) +static void OnRecvMessage(EventManager *manager, int sock, void *data, size_t len, sockaddr *addr) { if (data == nullptr || len <= 0) { return; @@ -195,6 +198,7 @@ static void OnRecvMessage(EventManager *manager, void *data, size_t len, sockadd auto *addr6 = reinterpret_cast(addr); remoteInfo.SetPort(ntohs(addr6->sin6_port)); } + remoteInfo.SetConnfd(sock); remoteInfo.SetSize(len); manager->EmitByUv(EVENT_MESSAGE, new MessageData(data, len, remoteInfo), CallbackTemplate); @@ -248,7 +252,7 @@ public: if (ret < 0) { return; } - OnRecvMessage(manager_, data, dataLen, reinterpret_cast(&addr4)); + OnRecvMessage(manager_, sock, data, dataLen, reinterpret_cast(&addr4)); return; } else if (family == AF_INET6) { sockaddr_in6 addr6 = {0}; @@ -258,7 +262,7 @@ public: if (ret < 0) { return; } - OnRecvMessage(manager_, data, dataLen, reinterpret_cast(&addr6)); + OnRecvMessage(manager_, sock, data, dataLen, reinterpret_cast(&addr6)); return; } } @@ -279,7 +283,7 @@ public: void OnMessage(int sock, void *data, size_t dataLen, sockaddr *addr) const override { - OnRecvMessage(manager_, data, dataLen, addr); + OnRecvMessage(manager_, sock, data, dataLen, addr); } }; @@ -361,7 +365,7 @@ static bool PollSendData(int sock, const char *data, size_t size, sockaddr *addr return true; } -static void PollRecvData(int sock, sockaddr *addr, socklen_t addrLen, const MessageCallback &callback) +static void PollRecvData(int sock, sockaddr *addr, socklen_t addrLen, bool isTcp, const MessageCallback &callback) { int bufferSize = DEFAULT_BUFFER_SIZE; int opt = 0; @@ -404,6 +408,10 @@ static void PollRecvData(int sock, sockaddr *addr, socklen_t addrLen, const Mess return; } if (recvLen == 0) { + if (isTcp) { + close(sock); + pthread_exit(NULL); + } continue; } @@ -412,7 +420,8 @@ static void PollRecvData(int sock, sockaddr *addr, socklen_t addrLen, const Mess callback.OnError(NO_MEMORY); return; } - NETSTACK_LOGI("copy ret = %{public}d", memcpy_s(data, recvLen, buf.get(), recvLen)); + NETSTACK_LOGI("copy ret = %{public}d, sock is %{public}d", + memcpy_s(data, recvLen, buf.get(), recvLen), sock); callback.OnMessage(sock, data, recvLen, addr); } } @@ -605,13 +614,13 @@ bool ExecUdpBind(BindContext *context) if (addr->sa_family == AF_INET) { auto pAddr4 = reinterpret_cast(malloc(sizeof(addr4))); NETSTACK_LOGI("copy ret = %{public}d", memcpy_s(pAddr4, sizeof(addr4), &addr4, sizeof(addr4))); - std::thread serviceThread(PollRecvData, context->GetSocketFd(), pAddr4, sizeof(addr4), + std::thread serviceThread(PollRecvData, context->GetSocketFd(), pAddr4, sizeof(addr4), false, UdpMessageCallback(context->GetManager())); serviceThread.detach(); } else if (addr->sa_family == AF_INET6) { auto pAddr6 = reinterpret_cast(malloc(sizeof(addr6))); NETSTACK_LOGI("copy ret = %{public}d", memcpy_s(pAddr6, sizeof(addr6), &addr6, sizeof(addr6))); - std::thread serviceThread(PollRecvData, context->GetSocketFd(), pAddr6, sizeof(addr6), + std::thread serviceThread(PollRecvData, context->GetSocketFd(), pAddr6, sizeof(addr6), false, UdpMessageCallback(context->GetManager())); serviceThread.detach(); } @@ -665,7 +674,7 @@ bool ExecConnect(ConnectContext *context) } NETSTACK_LOGI("connect success"); - std::thread serviceThread(PollRecvData, context->GetSocketFd(), nullptr, 0, + std::thread serviceThread(PollRecvData, context->GetSocketFd(), nullptr, 0, true, TcpMessageCallback(context->GetManager())); serviceThread.detach(); return true; @@ -677,9 +686,16 @@ bool ExecTcpSend(TcpSendContext *context) (void)encoding; /* no use for now */ + int sockfd = context->GetSocketFd(); + int connfd = context->options.GetConnfd(); + NETSTACK_LOGI("sockfd is %{public}d, TCPSendOptions connfd is %{public}d", sockfd, connfd); + if (connfd != 0) { + sockfd = connfd; + } + sa_family_t family; socklen_t len = sizeof(sa_family_t); - if (getsockname(context->GetSocketFd(), reinterpret_cast(&family), &len) < 0) { + if (getsockname(sockfd, reinterpret_cast(&family), &len) < 0) { NETSTACK_LOGE("get sock name failed"); context->SetErrorCode(ADDRESS_INVALID); return false; @@ -688,14 +704,14 @@ bool ExecTcpSend(TcpSendContext *context) if (family == AF_INET) { sockaddr_in addr4 = {0}; socklen_t len4 = sizeof(addr4); - int ret = getpeername(context->GetSocketFd(), reinterpret_cast(&addr4), &len4); + int ret = getpeername(sockfd, reinterpret_cast(&addr4), &len4); if (ret >= 0 && addr4.sin_port != 0) { connected = true; } } else if (family == AF_INET6) { sockaddr_in6 addr6 = {0}; socklen_t len6 = sizeof(addr6); - int ret = getpeername(context->GetSocketFd(), reinterpret_cast(&addr6), &len6); + int ret = getpeername(sockfd, reinterpret_cast(&addr6), &len6); if (ret >= 0 && addr6.sin6_port != 0) { connected = true; } @@ -707,7 +723,7 @@ bool ExecTcpSend(TcpSendContext *context) return false; } - if (!PollSendData(context->GetSocketFd(), context->options.GetData().c_str(), context->options.GetData().size(), + if (!PollSendData(sockfd, context->options.GetData().c_str(), context->options.GetData().size(), nullptr, 0)) { NETSTACK_LOGE("send errno %{public}d %{public}s", errno, strerror(errno)); context->SetErrorCode(errno); @@ -716,6 +732,36 @@ bool ExecTcpSend(TcpSendContext *context) return true; } +bool ExecTcpListen(TcpListenContext *context) +{ + NETSTACK_LOGI("tcp server start listen."); + int ret = listen(context->GetSocketFd(), BACK_LOG); + if (ret < 0) { + NETSTACK_LOGE("listen errno %{public}d %{public}s", errno, strerror(errno)); + return false; + } + + while(true) { + int connfd = accept(context->GetSocketFd(), NULL, NULL); + if (connfd == -1) { + if (errno == EWOULDBLOCK) { + sleep(1); + } else { + NETSTACK_LOGE("error when accepting connection errno %{public}d %{public}s\n", + errno, strerror(errno)); + return false; + } + } else { + NETSTACK_LOGI("accept new connfd is %{public}d", connfd); + MakeNonBlock(connfd); + std::thread serviceThread(PollRecvData, connfd, nullptr, 0, true, + TcpMessageCallback(context->GetManager())); + serviceThread.detach(); + } + } + NETSTACK_LOGI("tcp server listen end."); +} + bool ExecClose(CloseContext *context) { (void)context; @@ -917,6 +963,11 @@ napi_value ConnectCallback(ConnectContext *context) return NapiUtils::GetUndefined(context->GetEnv()); } +napi_value TcpListenCallback(TcpListenContext *context) +{ + return NapiUtils::GetUndefined(context->GetEnv()); +} + napi_value TcpSendCallback(TcpSendContext *context) { return NapiUtils::GetUndefined(context->GetEnv()); diff --git a/frameworks/js/napi/socket/socket_module/include/socket_module.h b/frameworks/js/napi/socket/socket_module/include/socket_module.h index 7b6c8c9eb..6668fe885 100644 --- a/frameworks/js/napi/socket/socket_module/include/socket_module.h +++ b/frameworks/js/napi/socket/socket_module/include/socket_module.h @@ -45,6 +45,7 @@ public: static constexpr const char *FUNCTION_BIND = "bind"; static constexpr const char *FUNCTION_CONNECT = "connect"; static constexpr const char *FUNCTION_SEND = "send"; + static constexpr const char *FUNCTION_LISTEN = "listen"; static constexpr const char *FUNCTION_CLOSE = "close"; static constexpr const char *FUNCTION_GET_REMOTE_ADDRESS = "getRemoteAddress"; static constexpr const char *FUNCTION_GET_STATE = "getState"; @@ -54,6 +55,7 @@ public: static napi_value Bind(napi_env env, napi_callback_info info); static napi_value Connect(napi_env env, napi_callback_info info); + static napi_value Listen(napi_env env, napi_callback_info info); static napi_value Send(napi_env env, napi_callback_info info); static napi_value Close(napi_env env, napi_callback_info info); static napi_value GetRemoteAddress(napi_env env, napi_callback_info info); diff --git a/frameworks/js/napi/socket/socket_module/src/socket_module.cpp b/frameworks/js/napi/socket/socket_module/src/socket_module.cpp index 0b17376d2..c64b14a5b 100644 --- a/frameworks/js/napi/socket/socket_module/src/socket_module.cpp +++ b/frameworks/js/napi/socket/socket_module/src/socket_module.cpp @@ -51,6 +51,7 @@ static const char *UDP_SET_EXTRA_OPTIONS_NAME = "UdpSetExtraOptions"; static const char *TCP_BIND_NAME = "TcpBind"; static const char *TCP_CONNECT_NAME = "TcpConnect"; +static const char *TCP_LISTEN_NAME = "TcpListen"; static const char *TCP_SEND_NAME = "TcpSend"; static const char *TCP_CLOSE_NAME = "TcpClose"; static const char *TCP_GET_STATE = "TcpGetState"; @@ -155,6 +156,7 @@ void SocketModuleExports::DefineTCPSocketClass(napi_env env, napi_value exports) std::initializer_list properties = { DECLARE_NAPI_FUNCTION(TCPSocket::FUNCTION_BIND, TCPSocket::Bind), DECLARE_NAPI_FUNCTION(TCPSocket::FUNCTION_CONNECT, TCPSocket::Connect), + DECLARE_NAPI_FUNCTION(TCPSocket::FUNCTION_LISTEN, TCPSocket::Listen), DECLARE_NAPI_FUNCTION(TCPSocket::FUNCTION_SEND, TCPSocket::Send), DECLARE_NAPI_FUNCTION(TCPSocket::FUNCTION_CLOSE, TCPSocket::Close), DECLARE_NAPI_FUNCTION(TCPSocket::FUNCTION_GET_REMOTE_ADDRESS, TCPSocket::GetRemoteAddress), @@ -223,6 +225,11 @@ napi_value SocketModuleExports::TCPSocket::Connect(napi_env env, napi_callback_i return SOCKET_INTERFACE(ConnectContext, ExecConnect, ConnectCallback, nullptr, TCP_CONNECT_NAME); } +napi_value SocketModuleExports::TCPSocket::Listen(napi_env env, napi_callback_info info) +{ + return SOCKET_INTERFACE(TcpListenContext, ExecTcpListen, TcpListenCallback, nullptr, TCP_LISTEN_NAME); +} + napi_value SocketModuleExports::TCPSocket::Send(napi_env env, napi_callback_info info) { return SOCKET_INTERFACE(TcpSendContext, ExecTcpSend, TcpSendCallback, nullptr, TCP_SEND_NAME); diff --git a/frameworks/js/napi/socket/task_queue/include/task_queue.h b/frameworks/js/napi/socket/task_queue/include/task_queue.h index 57a56c79a..fa3a21d11 100644 --- a/frameworks/js/napi/socket/task_queue/include/task_queue.h +++ b/frameworks/js/napi/socket/task_queue/include/task_queue.h @@ -23,6 +23,7 @@ enum class TaskPriority { CLOSE, SEND, CONNECT, + LISTEN, BIND, SET_OPTIONS, }; diff --git a/interfaces/kits/js/@ohos.net.socket.d.ts b/interfaces/kits/js/@ohos.net.socket.d.ts index fb88669e1..579d08915 100644 --- a/interfaces/kits/js/@ohos.net.socket.d.ts +++ b/interfaces/kits/js/@ohos.net.socket.d.ts @@ -100,6 +100,10 @@ declare namespace socket { * Port number. The value ranges from 0 to 65535. */ port: number; + /** + * Socket descriptor returned by accept to connect with the client. + */ + connfd?: number; /** * Length of the server response message, in bytes. */ @@ -201,6 +205,10 @@ declare namespace socket { * Character encoding format. */ encoding?: string; + /** + * Socket descriptor returned by accept to connect with the client. + */ + connfd?: number; } export interface TCPExtraOptions extends ExtraOptionsBase { @@ -250,6 +258,13 @@ declare namespace socket { send(options: TCPSendOptions, callback: AsyncCallback): void; send(options: TCPSendOptions): Promise; + /** + * Start a server listening for connections. + * @permission ohos.permission.INTERNET + */ + listen(callback: AsyncCallback): void; + listen(): Promise; + /** * Closes a TCPSocket connection. * @permission ohos.permission.INTERNET -- Gitee