mirror of
				https://gitee.com/jiuyilian/embedded-framework.git
				synced 2025-10-24 18:20:15 -04:00 
			
		
		
		
	Backup:TcpModule.
This commit is contained in:
		
							parent
							
								
									a2f8103fa5
								
							
						
					
					
						commit
						6f6e8eb7cd
					
				| 
						 | 
				
			
			@ -12,8 +12,8 @@
 | 
			
		|||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef IIPCCONFIG_H
 | 
			
		||||
#define IIPCCONFIG_H
 | 
			
		||||
#ifndef I_IPC_CONFIG_H
 | 
			
		||||
#define I_IPC_CONFIG_H
 | 
			
		||||
#include "StatusCode.h"
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <memory>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,8 +12,8 @@
 | 
			
		|||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef GTESTUSING_H
 | 
			
		||||
#define GTESTUSING_H
 | 
			
		||||
#ifndef GTEST_USING_H
 | 
			
		||||
#define GTEST_USING_H
 | 
			
		||||
#include <gmock/gmock.h>
 | 
			
		||||
#include <gtest/gtest.h>
 | 
			
		||||
using ::testing::_;
 | 
			
		||||
| 
						 | 
				
			
			@ -41,11 +41,11 @@ using ::testing::ReturnRefOfCopy;
 | 
			
		|||
using ::testing::ReturnRoundRobin;
 | 
			
		||||
using ::testing::SaveArg;
 | 
			
		||||
using ::testing::SetArgPointee;
 | 
			
		||||
using ::testing::SetArgReferee;
 | 
			
		||||
using ::testing::SetArgumentPointee;
 | 
			
		||||
using ::testing::Unused;
 | 
			
		||||
using ::testing::WithArgs;
 | 
			
		||||
using ::testing::internal::BuiltInDefaultValue;
 | 
			
		||||
using ::testing::SetArgReferee;
 | 
			
		||||
// using ::testing::Mock::VerifyAndClearExpectations;
 | 
			
		||||
using ::testing::Mock;
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -18,10 +18,6 @@ link_directories(
 | 
			
		|||
    ${EXTERNAL_LIBS_OUTPUT_PATH}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
aux_source_directory(. SRC_FILES)
 | 
			
		||||
aux_source_directory(${TEST_SOURCE_PATH}/middleware/IpcConfig/src SRC_FILES)
 | 
			
		||||
set(TARGET_NAME AllTest)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,7 +32,7 @@ endif()
 | 
			
		|||
if(${TARGET_PLATFORM} MATCHES ${DEFINE_LINUX})
 | 
			
		||||
    target_link_libraries(${TARGET_NAME} LinuxApiMock)
 | 
			
		||||
endif()
 | 
			
		||||
# if ("${COMPILE_IMPROVE_SUPPORT}" MATCHES "true")
 | 
			
		||||
if ("${COMPILE_IMPROVE_SUPPORT}" MATCHES "true")
 | 
			
		||||
add_custom_target(
 | 
			
		||||
    TcpModuleTest_code_check
 | 
			
		||||
    COMMAND ${CLANG_TIDY_EXE}
 | 
			
		||||
| 
						 | 
				
			
			@ -61,7 +61,7 @@ add_custom_command(
 | 
			
		|||
    COMMAND make TcpModuleTest_code_format
 | 
			
		||||
    WORKING_DIRECTORY ${PLATFORM_PATH}/cmake-shell/
 | 
			
		||||
)
 | 
			
		||||
# endif()
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
define_file_name(${TARGET_NAME})
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,6 +16,7 @@
 | 
			
		|||
#include "TcpModule.h"
 | 
			
		||||
#include <gmock/gmock.h>
 | 
			
		||||
#include <gtest/gtest.h>
 | 
			
		||||
#include <thread>
 | 
			
		||||
namespace TcpModuleTest
 | 
			
		||||
{
 | 
			
		||||
// ../output_files/test/bin/TcpModuleTest --gtest_filter=TcpModuleTest.UNIT_TcpModule_AUTO_IllegalObject
 | 
			
		||||
| 
						 | 
				
			
			@ -24,8 +25,33 @@ namespace TcpModuleTest
 | 
			
		|||
 */
 | 
			
		||||
TEST(TcpModuleTest, UNIT_TcpModule_AUTO_IllegalObject)
 | 
			
		||||
{
 | 
			
		||||
    static void *tcpClientAccept = nullptr;
 | 
			
		||||
    TcpParam param = {
 | 
			
		||||
        .mIp = "127.0.0.1",
 | 
			
		||||
        .mPort = 9876,
 | 
			
		||||
        .mReadFunc = [](const void *p, const size_t len, void *context) -> void {
 | 
			
		||||
            return;
 | 
			
		||||
        },
 | 
			
		||||
        .mAcceptClientFunc = [](void *object, const char *ip) -> void {
 | 
			
		||||
            LogInfo("accept client, peer ip: %s", ip);
 | 
			
		||||
            tcpClientAccept = object;
 | 
			
		||||
            return;
 | 
			
		||||
        },
 | 
			
		||||
    };
 | 
			
		||||
    CreateLogModule();
 | 
			
		||||
    ILogInit(LOG_INSTANCE_TYPE_END);
 | 
			
		||||
    void *tcpServer = CreateTcpServer(param);
 | 
			
		||||
    std::this_thread::sleep_for(std::chrono::milliseconds(500));
 | 
			
		||||
    void *tcpClient = CreateTcpClient(param);
 | 
			
		||||
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
 | 
			
		||||
    TcpClientWrite(tcpClient, "123456789", strlen("123456789"));
 | 
			
		||||
    std::this_thread::sleep_for(std::chrono::milliseconds(3000));
 | 
			
		||||
    if (nullptr != tcpClient) {
 | 
			
		||||
        FreeTcpClient(tcpClient);
 | 
			
		||||
    }
 | 
			
		||||
    if (nullptr != tcpServer) {
 | 
			
		||||
        FreeTcpServer(tcpServer);
 | 
			
		||||
    }
 | 
			
		||||
    ILogUnInit();
 | 
			
		||||
}
 | 
			
		||||
} // namespace TcpModuleTest
 | 
			
		||||
| 
						 | 
				
			
			@ -21,7 +21,7 @@ static bool ObjectCheck(void *object)
 | 
			
		|||
        LogError("nullptr object!\n");
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    if (*((const char **)(((char *)object) - sizeof(IConfigBase))) != GetConfigBaseModuleName()) {
 | 
			
		||||
    if (*((const char **)(((char *)object) - sizeof(IConfigBaseHeader))) != GetConfigBaseModuleName()) {
 | 
			
		||||
        LogError("Illegal object!\n");
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -47,7 +47,7 @@ void CloseConfigFile(void *object)
 | 
			
		|||
    if (ObjectCheck(object) == true) {
 | 
			
		||||
        (*(std::shared_ptr<IConfigBase> *)object)->CloseConfigFile();
 | 
			
		||||
        (*(std::shared_ptr<IConfigBase> *)object).reset();
 | 
			
		||||
        free(((char *)object) - sizeof(IConfigBase)); // TODO: bug?
 | 
			
		||||
        free(((char *)object) - sizeof(IConfigBaseHeader)); // TODO: bug?
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
StatusCode ConfigGetInt(void *object, const char *name, int *value)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,7 @@ include_directories(
 | 
			
		|||
    ${UTILS_SOURCE_PATH}/LinuxApi/include
 | 
			
		||||
    ${UTILS_SOURCE_PATH}/StatusCode/include
 | 
			
		||||
    ${UTILS_SOURCE_PATH}/Log/include
 | 
			
		||||
    ${EXTERNAL_SOURCE_PATH}/libhv/libhv-1.3.2/include/hv
 | 
			
		||||
)
 | 
			
		||||
# link_directories(
 | 
			
		||||
#     ${EXTERNAL_SOURCE_PATH}/libconfig/libconfig-1.7.3/lib/.libs
 | 
			
		||||
| 
						 | 
				
			
			@ -17,9 +18,9 @@ aux_source_directory(./src SRC_FILES)
 | 
			
		|||
 | 
			
		||||
set(TARGET_NAME TcpModule)
 | 
			
		||||
add_library(${TARGET_NAME} STATIC ${SRC_FILES})
 | 
			
		||||
target_link_libraries(${TARGET_NAME} LinuxApi StatusCode Log)
 | 
			
		||||
target_link_libraries(${TARGET_NAME} LinuxApi hv_static StatusCode Log)
 | 
			
		||||
 | 
			
		||||
# if ("${COMPILE_IMPROVE_SUPPORT}" MATCHES "true")
 | 
			
		||||
if ("${COMPILE_IMPROVE_SUPPORT}" MATCHES "true")
 | 
			
		||||
add_custom_target(
 | 
			
		||||
    TcpModule_code_check
 | 
			
		||||
    COMMAND ${CLANG_TIDY_EXE}
 | 
			
		||||
| 
						 | 
				
			
			@ -46,7 +47,7 @@ add_custom_command(
 | 
			
		|||
    COMMAND make TcpModule_code_format
 | 
			
		||||
    WORKING_DIRECTORY ${PLATFORM_PATH}/cmake-shell/
 | 
			
		||||
)
 | 
			
		||||
# endif()
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
define_file_name(${TARGET_NAME})
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,22 +14,27 @@
 | 
			
		|||
 */
 | 
			
		||||
#ifndef TCP_MODULE_H
 | 
			
		||||
#define TCP_MODULE_H
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
typedef void (*TcpReadFunction)(void *, const int, void *);
 | 
			
		||||
typedef void (*TcpReadFunction)(const void *, const size_t, void *);
 | 
			
		||||
typedef void (*TcpAcceptClientFunction)(void *, const char *);
 | 
			
		||||
typedef struct tcp_parm
 | 
			
		||||
{
 | 
			
		||||
    const char *mIp;
 | 
			
		||||
    const int mPort;
 | 
			
		||||
    const TcpReadFunction mReadFunc;
 | 
			
		||||
} TcpPram;
 | 
			
		||||
void *CreateTcpServer(const TcpPram param);
 | 
			
		||||
void FreeTcpServer(void *pointer);
 | 
			
		||||
int TcpServerWrite(void *object, void *buf, const int bufLenght);
 | 
			
		||||
void *CreateTcpClient(const TcpPram param);
 | 
			
		||||
void FreeTcpClient(void *pointer);
 | 
			
		||||
int TcpClientWrite(void *object, void *buf, const int bufLenght);
 | 
			
		||||
    TcpReadFunction mReadFunc; // TODO: delete this memeber
 | 
			
		||||
    TcpAcceptClientFunction mAcceptClientFunc;
 | 
			
		||||
} TcpParam;
 | 
			
		||||
void *CreateTcpServer(const TcpParam param);
 | 
			
		||||
void FreeTcpServer(void *object);
 | 
			
		||||
int AcceptClientSetReadFunc(void *object, TcpReadFunction readFunc);
 | 
			
		||||
int AcceptClientWrite(void *object, void *buf, const size_t bufLenght);
 | 
			
		||||
void *CreateTcpClient(const TcpParam param);
 | 
			
		||||
void FreeTcpClient(void *object);
 | 
			
		||||
ssize_t TcpClientWrite(void *object, const void *buf, const size_t bufLenght);
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,4 +11,22 @@
 | 
			
		|||
 * 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 "ITcpClient.h"
 | 
			
		||||
#include "ILog.h"
 | 
			
		||||
#include <cstring>
 | 
			
		||||
void ITcpClient::Init(void)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
void ITcpClient::UnInit(void)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
ssize_t ITcpClient::Write(const void *buf, const size_t bufLenght)
 | 
			
		||||
{
 | 
			
		||||
    return WRITE_ERROR;
 | 
			
		||||
}
 | 
			
		||||
static const char *TCP_CLIENT_NAME = "tcp_client";
 | 
			
		||||
const char *GetTcpClientModuleName(void)
 | 
			
		||||
{
 | 
			
		||||
    return TCP_CLIENT_NAME;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										39
									
								
								utils/TcpModule/src/ITcpClient.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								utils/TcpModule/src/ITcpClient.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,39 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2023 Fancy Code.
 | 
			
		||||
 * 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 I_TCP_CLIENT_H
 | 
			
		||||
#define I_TCP_CLIENT_H
 | 
			
		||||
#include "StatusCode.h"
 | 
			
		||||
#include <memory>
 | 
			
		||||
constexpr int WRITE_ERROR = -1;
 | 
			
		||||
class ITcpClient
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    ITcpClient() = default;
 | 
			
		||||
    virtual ~ITcpClient() = default;
 | 
			
		||||
    virtual void Init(void);
 | 
			
		||||
    virtual void UnInit(void);
 | 
			
		||||
    virtual ssize_t Write(const void *buf, const size_t bufLenght);
 | 
			
		||||
};
 | 
			
		||||
typedef struct i_tcp_client_header
 | 
			
		||||
{
 | 
			
		||||
    const char *mCheckName;
 | 
			
		||||
} ITcpClientHeader;
 | 
			
		||||
typedef struct tcp_client
 | 
			
		||||
{
 | 
			
		||||
    ITcpClientHeader mHeader;
 | 
			
		||||
    std::shared_ptr<ITcpClient> mTcpClient;
 | 
			
		||||
} TcpClient;
 | 
			
		||||
const char *GetTcpClientModuleName(void);
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -11,4 +11,26 @@
 | 
			
		|||
 * 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 "ITcpServer.h"
 | 
			
		||||
#include "ILog.h"
 | 
			
		||||
#include <cstring>
 | 
			
		||||
void ITcpClientAccept::Readed(const void *data, size_t length)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
void ITcpServer::Init(void)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
void ITcpServer::UnInit(void)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
static const char *TCP_SERVER_NAME = "tcp_server";
 | 
			
		||||
static const char *TCP_CLIENT_ACCEPT_NAME = "tcp_client_accept";
 | 
			
		||||
const char *GetTcpServerModuleName(void)
 | 
			
		||||
{
 | 
			
		||||
    return TCP_SERVER_NAME;
 | 
			
		||||
}
 | 
			
		||||
const char *GetTcpClientAcceptName(void)
 | 
			
		||||
{
 | 
			
		||||
    return TCP_CLIENT_ACCEPT_NAME;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										50
									
								
								utils/TcpModule/src/ITcpServer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								utils/TcpModule/src/ITcpServer.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,50 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2023 Fancy Code.
 | 
			
		||||
 * 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 I_TCP_SERVER_H
 | 
			
		||||
#define I_TCP_SERVER_H
 | 
			
		||||
#include "StatusCode.h"
 | 
			
		||||
#include <memory>
 | 
			
		||||
class ITcpClientAccept
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    ITcpClientAccept() = default;
 | 
			
		||||
    virtual ~ITcpClientAccept() = default;
 | 
			
		||||
    virtual void Readed(const void *data, size_t length);
 | 
			
		||||
};
 | 
			
		||||
class ITcpServer
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    ITcpServer() = default;
 | 
			
		||||
    virtual ~ITcpServer() = default;
 | 
			
		||||
    virtual void Init(void);
 | 
			
		||||
    virtual void UnInit(void);
 | 
			
		||||
};
 | 
			
		||||
typedef struct i_tcp_server_header
 | 
			
		||||
{
 | 
			
		||||
    const char *mCheckName;
 | 
			
		||||
} ITcpServerHeader;
 | 
			
		||||
typedef struct tcp_server
 | 
			
		||||
{
 | 
			
		||||
    ITcpServerHeader mHeader;
 | 
			
		||||
    std::shared_ptr<ITcpServer> mTcpServer;
 | 
			
		||||
} TcpServer;
 | 
			
		||||
typedef struct tcp_client_accept
 | 
			
		||||
{
 | 
			
		||||
    ITcpServerHeader mHeader;
 | 
			
		||||
    std::shared_ptr<ITcpClientAccept> mTcpClientAccept;
 | 
			
		||||
} TcpClientAccept;
 | 
			
		||||
const char *GetTcpServerModuleName(void);
 | 
			
		||||
const char *GetTcpClientAcceptName(void);
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										117
									
								
								utils/TcpModule/src/TcpClientImpl.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								utils/TcpModule/src/TcpClientImpl.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,117 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2023 Fancy Code.
 | 
			
		||||
 * 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 "TcpClientImpl.h"
 | 
			
		||||
#include "ILog.h"
 | 
			
		||||
#include <cstring>
 | 
			
		||||
TcpClientImpl::TcpClientImpl(const TcpParam param) : mParam(param)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
static void on_message(hio_t *io, void *buf, int len)
 | 
			
		||||
{
 | 
			
		||||
    LogInfo("onmessage: %.*s\n", len, (char *)buf);
 | 
			
		||||
    TcpClientImpl *cli = (TcpClientImpl *)hevent_userdata(io);
 | 
			
		||||
    // ...
 | 
			
		||||
}
 | 
			
		||||
static void on_connect(hio_t *io)
 | 
			
		||||
{
 | 
			
		||||
    LogInfo("onconnect: connfd=%d\n", hio_fd(io));
 | 
			
		||||
    TcpClientImpl *cli = (TcpClientImpl *)hevent_userdata(io);
 | 
			
		||||
    // cli->connected = 1;
 | 
			
		||||
 | 
			
		||||
    // hio_write(io, "hello\r\n", 7);
 | 
			
		||||
 | 
			
		||||
    hio_setcb_read(io, on_message);
 | 
			
		||||
    hio_read(io);
 | 
			
		||||
}
 | 
			
		||||
static void on_close(hio_t *io)
 | 
			
		||||
{
 | 
			
		||||
    LogInfo("onclose: connfd=%d error=%d\n", hio_fd(io), hio_error(io));
 | 
			
		||||
    TcpClientImpl *cli = (TcpClientImpl *)hevent_userdata(io);
 | 
			
		||||
    // cli->connected = 0;
 | 
			
		||||
    // reconnect
 | 
			
		||||
    // if (cli->reconn_setting && reconn_setting_can_retry(cli->reconn_setting)) {
 | 
			
		||||
    //     uint32_t delay = reconn_setting_calc_delay(cli->reconn_setting);
 | 
			
		||||
    //     LogInfo("reconnect cnt=%d, delay=%d ...\n", cli->reconn_setting->cur_retry_cnt,
 | 
			
		||||
    //     cli->reconn_setting->cur_delay); cli->reconn_timer = htimer_add(cli->mLoop, reconnect_timer_cb, delay, 1);
 | 
			
		||||
    //     hevent_set_userdata(cli->reconn_timer, cli);
 | 
			
		||||
    // }
 | 
			
		||||
}
 | 
			
		||||
void TcpClientImpl::Init(void)
 | 
			
		||||
{
 | 
			
		||||
    constexpr int NO_FALGS = 0;
 | 
			
		||||
    mLoop = hloop_new(NO_FALGS);
 | 
			
		||||
    if (nullptr == mLoop) {
 | 
			
		||||
        LogError("TcpClientImpl::Init hloop_new failed.\n");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    hio_t *io = hio_create_socket(mLoop, mParam.mIp, mParam.mPort, HIO_TYPE_TCP, HIO_CLIENT_SIDE);
 | 
			
		||||
    if (nullptr == io) {
 | 
			
		||||
        LogError("TcpClientImpl::Init hio_create_socket failed.\n");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    hevent_set_userdata(io, this);
 | 
			
		||||
    hio_setcb_connect(io, on_connect);
 | 
			
		||||
    hio_setcb_close(io, on_close);
 | 
			
		||||
    hio_connect(io);
 | 
			
		||||
    mIo = io;
 | 
			
		||||
    std::shared_ptr<TcpClientImpl> impl = std::dynamic_pointer_cast<TcpClientImpl>(shared_from_this());
 | 
			
		||||
    auto recvThread = [](std::shared_ptr<TcpClientImpl> tcpClient) {
 | 
			
		||||
        tcpClient->Loop();
 | 
			
		||||
    };
 | 
			
		||||
    mTcpClientThread = std::thread(recvThread, impl);
 | 
			
		||||
}
 | 
			
		||||
void TcpClientImpl::UnInit(void)
 | 
			
		||||
{
 | 
			
		||||
    if (nullptr != mLoop) {
 | 
			
		||||
        LogInfo("Stop loop.\n");
 | 
			
		||||
        hloop_stop(mLoop);
 | 
			
		||||
    }
 | 
			
		||||
    if (mTcpClientThread.joinable()) {
 | 
			
		||||
        mTcpClientThread.join();
 | 
			
		||||
    }
 | 
			
		||||
    hloop_free(&mLoop);
 | 
			
		||||
    mLoop = nullptr;
 | 
			
		||||
    mIo = nullptr;
 | 
			
		||||
}
 | 
			
		||||
ssize_t TcpClientImpl::Write(const void *buf, const size_t bufLenght)
 | 
			
		||||
{
 | 
			
		||||
    if (nullptr == mIo) {
 | 
			
		||||
        LogError("mIo is nullptr.\n");
 | 
			
		||||
        return WRITE_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
    return hio_write(mIo, buf, bufLenght);
 | 
			
		||||
}
 | 
			
		||||
void TcpClientImpl::Loop(void)
 | 
			
		||||
{
 | 
			
		||||
    if (nullptr == mLoop) {
 | 
			
		||||
        LogError("mLoop is null\n");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    hloop_run(mLoop);
 | 
			
		||||
}
 | 
			
		||||
std::shared_ptr<ITcpClient> *NewTcpClient(const TcpParam param)
 | 
			
		||||
{
 | 
			
		||||
    LogInfo("Create tcp server object.\n");
 | 
			
		||||
    TcpClient *impl = (TcpClient *)malloc(sizeof(TcpClient));
 | 
			
		||||
    if (nullptr == impl) {
 | 
			
		||||
        LogError("NewTcpServer::malloc failed.\n");
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    TcpClient tmp;
 | 
			
		||||
    memcpy((void *)impl, (void *)&tmp, sizeof(TcpClient));
 | 
			
		||||
    impl->mHeader.mCheckName = GetTcpClientModuleName();
 | 
			
		||||
    impl->mTcpClient = std::make_shared<TcpClientImpl>(param);
 | 
			
		||||
    return (std::shared_ptr<ITcpClient> *)(((char *)impl) + sizeof(ITcpClientHeader));
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										41
									
								
								utils/TcpModule/src/TcpClientImpl.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								utils/TcpModule/src/TcpClientImpl.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,41 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2023 Fancy Code.
 | 
			
		||||
 * 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 TCP_CLIENT_IMPL_H
 | 
			
		||||
#define TCP_CLIENT_IMPL_H
 | 
			
		||||
#include "ITcpClient.h"
 | 
			
		||||
#include "TcpModule.h"
 | 
			
		||||
#include "hloop.h"
 | 
			
		||||
#include "hsocket.h"
 | 
			
		||||
#include "hssl.h"
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <thread>
 | 
			
		||||
class TcpClientImpl : public ITcpClient, public std::enable_shared_from_this<TcpClientImpl>
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    TcpClientImpl(const TcpParam param);
 | 
			
		||||
    virtual ~TcpClientImpl() = default;
 | 
			
		||||
    void Init(void) override;
 | 
			
		||||
    void UnInit(void) override;
 | 
			
		||||
    ssize_t Write(const void *buf, const size_t bufLenght) override;
 | 
			
		||||
    void Loop(void);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    hloop_t* mLoop;
 | 
			
		||||
    hio_t *mIo;
 | 
			
		||||
    const TcpParam mParam;
 | 
			
		||||
    std::thread mTcpClientThread;
 | 
			
		||||
};
 | 
			
		||||
std::shared_ptr<ITcpClient> *NewTcpClient(const TcpParam param);
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -13,9 +13,71 @@
 | 
			
		|||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
#include "TcpModule.h"
 | 
			
		||||
#include "ILog.h"
 | 
			
		||||
#include "ITcpServer.h"
 | 
			
		||||
#include "TcpClientImpl.h"
 | 
			
		||||
#include "TcpModuleImpl.h"
 | 
			
		||||
void *CreateTcpServer(const TcpPram param)
 | 
			
		||||
#include "TcpModuleMakePtr.h"
 | 
			
		||||
static bool TcpServerObjectCheck(void *object)
 | 
			
		||||
{
 | 
			
		||||
    //
 | 
			
		||||
    return NewTcpServer(param);
 | 
			
		||||
    if (nullptr == object) {
 | 
			
		||||
        LogError("nullptr object!\n");
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    if (*((const char **)(((char *)object) - sizeof(ITcpServerHeader))) != GetTcpServerModuleName()) {
 | 
			
		||||
        LogError("Illegal object!\n");
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
static bool TcpClientObjectCheck(void *object)
 | 
			
		||||
{
 | 
			
		||||
    if (nullptr == object) {
 | 
			
		||||
        LogError("nullptr object!\n");
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    if (*((const char **)(((char *)object) - sizeof(ITcpClientHeader))) != GetTcpClientModuleName()) {
 | 
			
		||||
        LogError("Illegal object!\n");
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
void *CreateTcpServer(const TcpParam param)
 | 
			
		||||
{
 | 
			
		||||
    std::shared_ptr<ITcpServer> *server = TcpModuleMakePtr::GetInstance()->CreateTcpServer(param);
 | 
			
		||||
    if (nullptr != *server) {
 | 
			
		||||
        (*server)->Init();
 | 
			
		||||
    }
 | 
			
		||||
    return server;
 | 
			
		||||
}
 | 
			
		||||
void FreeTcpServer(void *object)
 | 
			
		||||
{
 | 
			
		||||
    if (TcpServerObjectCheck(object) == true) {
 | 
			
		||||
        (*(std::shared_ptr<ITcpServer> *)object)->UnInit();
 | 
			
		||||
        (*(std::shared_ptr<ITcpServer> *)object).reset();
 | 
			
		||||
        free(((char *)object) - sizeof(ITcpServerHeader)); // TODO: bug?
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
void *CreateTcpClient(const TcpParam param)
 | 
			
		||||
{
 | 
			
		||||
    std::shared_ptr<ITcpClient> *client = TcpModuleMakePtr::GetInstance()->CreateTcpClient(param);
 | 
			
		||||
    if (nullptr != *client) {
 | 
			
		||||
        (*client)->Init();
 | 
			
		||||
    }
 | 
			
		||||
    return client;
 | 
			
		||||
}
 | 
			
		||||
void FreeTcpClient(void *object)
 | 
			
		||||
{
 | 
			
		||||
    if (TcpClientObjectCheck(object) == true) {
 | 
			
		||||
        (*(std::shared_ptr<ITcpClient> *)object)->UnInit();
 | 
			
		||||
        (*(std::shared_ptr<ITcpClient> *)object).reset();
 | 
			
		||||
        free(((char *)object) - sizeof(ITcpClientHeader)); // TODO: bug?
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
ssize_t TcpClientWrite(void *object, const void *buf, const size_t bufLenght)
 | 
			
		||||
{
 | 
			
		||||
    if (TcpClientObjectCheck(object) == true) {
 | 
			
		||||
        return (*(std::shared_ptr<ITcpClient> *)object)->Write(buf, bufLenght);
 | 
			
		||||
    }
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -15,26 +15,26 @@
 | 
			
		|||
#include "TcpModuleImpl.h"
 | 
			
		||||
#include "ILog.h"
 | 
			
		||||
#include <cstring>
 | 
			
		||||
static const char *TCP_MODULE_NAME = "tcp_module";
 | 
			
		||||
const char *GetTcpModuleName(void)
 | 
			
		||||
{
 | 
			
		||||
    return TCP_MODULE_NAME;
 | 
			
		||||
}
 | 
			
		||||
void *NewTcpModuleImpl(const TcpPram &tcpParam)
 | 
			
		||||
{
 | 
			
		||||
    if (nullptr == tcpParam.mIp) {
 | 
			
		||||
        LogError("Parament error, nullptr == tcpParam.mIp\n");
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    LogInfo("Create the tcp module object.\n");
 | 
			
		||||
    TcpServer *impl = (TcpServer *)malloc(sizeof(TcpServer));
 | 
			
		||||
    TcpServer tmp;
 | 
			
		||||
    memcpy((void *)impl, (void *)&tmp, sizeof(TcpServer));
 | 
			
		||||
    impl->mHeader.mCheckName = TCP_MODULE_NAME;
 | 
			
		||||
    impl->mTcpImpl = std::make_shared<TcpModuleImpl>(tcpParam);
 | 
			
		||||
    return (void *)(((char *)impl) + sizeof(TcpModuleHeader));
 | 
			
		||||
}
 | 
			
		||||
void *NewTcpServer(const TcpPram &tcpParam)
 | 
			
		||||
{
 | 
			
		||||
    return nullptr;
 | 
			
		||||
}
 | 
			
		||||
// static const char *TCP_MODULE_NAME = "tcp_module";
 | 
			
		||||
// const char *GetTcpModuleName(void)
 | 
			
		||||
// {
 | 
			
		||||
//     return TCP_MODULE_NAME;
 | 
			
		||||
// }
 | 
			
		||||
// void *NewTcpModuleImpl(const TcpParam &tcpParam)
 | 
			
		||||
// {
 | 
			
		||||
//     if (nullptr == tcpParam.mIp) {
 | 
			
		||||
//         LogError("Parament error, nullptr == tcpParam.mIp\n");
 | 
			
		||||
//         return nullptr;
 | 
			
		||||
//     }
 | 
			
		||||
//     LogInfo("Create the tcp module object.\n");
 | 
			
		||||
//     TcpServer *impl = (TcpServer *)malloc(sizeof(TcpServer));
 | 
			
		||||
//     TcpServer tmp;
 | 
			
		||||
//     memcpy((void *)impl, (void *)&tmp, sizeof(TcpServer));
 | 
			
		||||
//     impl->mHeader.mCheckName = TCP_MODULE_NAME;
 | 
			
		||||
//     impl->mTcpImpl = std::make_shared<TcpModuleImpl>(tcpParam);
 | 
			
		||||
//     return (void *)(((char *)impl) + sizeof(TcpModuleHeader));
 | 
			
		||||
// }
 | 
			
		||||
// void *NewTcpServer(const TcpParam &tcpParam)
 | 
			
		||||
// {
 | 
			
		||||
//     return nullptr;
 | 
			
		||||
// }
 | 
			
		||||
| 
						 | 
				
			
			@ -17,36 +17,36 @@
 | 
			
		|||
#include "StatusCode.h"
 | 
			
		||||
#include "TcpModule.h"
 | 
			
		||||
#include <memory>
 | 
			
		||||
#define TCP_MODULE_INIT_NAME "UART"
 | 
			
		||||
typedef struct tcp_module_header
 | 
			
		||||
{
 | 
			
		||||
    const char *mCheckName;
 | 
			
		||||
} TcpModuleHeader;
 | 
			
		||||
class TcpModuleImpl
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    TcpModuleImpl(const TcpPram &uatrInfo);
 | 
			
		||||
    virtual ~TcpModuleImpl() = default;
 | 
			
		||||
// #define TCP_MODULE_INIT_NAME "UART"
 | 
			
		||||
// typedef struct tcp_module_header
 | 
			
		||||
// {
 | 
			
		||||
//     const char *mCheckName;
 | 
			
		||||
// } TcpModuleHeader;
 | 
			
		||||
// class TcpModuleImpl
 | 
			
		||||
// {
 | 
			
		||||
// public:
 | 
			
		||||
//     TcpModuleImpl(const TcpParam &uatrInfo);
 | 
			
		||||
//     virtual ~TcpModuleImpl() = default;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    const StatusCode SetConfig(void);
 | 
			
		||||
// private:
 | 
			
		||||
//     const StatusCode SetConfig(void);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    const TcpPram mUatrInfo;
 | 
			
		||||
    int mFd;
 | 
			
		||||
};
 | 
			
		||||
// private:
 | 
			
		||||
//     const TcpParam mUatrInfo;
 | 
			
		||||
//     int mFd;
 | 
			
		||||
// };
 | 
			
		||||
// TODO: There may be a CPU byte alignment bug.
 | 
			
		||||
typedef struct tcp_server TcpServer;
 | 
			
		||||
typedef struct tcp_server
 | 
			
		||||
{
 | 
			
		||||
    TcpModuleHeader mHeader;
 | 
			
		||||
    std::shared_ptr<TcpModuleImpl> mTcpImpl;
 | 
			
		||||
} TcpServer;
 | 
			
		||||
void *NewTcpModuleImpl(const TcpPram &tcpParam);
 | 
			
		||||
void *NewTcpServer(const TcpPram &tcpParam);
 | 
			
		||||
static inline TcpServer *TcpModuleImplConvert(void *object)
 | 
			
		||||
{
 | 
			
		||||
    return ((TcpServer *)(((char *)object) - sizeof(TcpModuleHeader)));
 | 
			
		||||
}
 | 
			
		||||
const char *GetTcpModuleName(void);
 | 
			
		||||
// typedef struct tcp_server TcpServer;
 | 
			
		||||
// typedef struct tcp_server
 | 
			
		||||
// {
 | 
			
		||||
//     TcpModuleHeader mHeader;
 | 
			
		||||
//     std::shared_ptr<TcpModuleImpl> mTcpImpl;
 | 
			
		||||
// } TcpServer;
 | 
			
		||||
// void *NewTcpModuleImpl(const TcpParam &tcpParam);
 | 
			
		||||
// void *NewTcpServer(const TcpParam &tcpParam);
 | 
			
		||||
// static inline TcpServer *TcpModuleImplConvert(void *object)
 | 
			
		||||
// {
 | 
			
		||||
//     return ((TcpServer *)(((char *)object) - sizeof(TcpModuleHeader)));
 | 
			
		||||
// }
 | 
			
		||||
// const char *GetTcpModuleName(void);
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -11,4 +11,24 @@
 | 
			
		|||
 * 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 "TcpModuleMakePtr.h"
 | 
			
		||||
#include "ILog.h"
 | 
			
		||||
#include "TcpServerImpl.h"
 | 
			
		||||
#include "TcpClientImpl.h"
 | 
			
		||||
std::shared_ptr<TcpModuleMakePtr> &TcpModuleMakePtr::GetInstance(std::shared_ptr<TcpModuleMakePtr> *impl)
 | 
			
		||||
{
 | 
			
		||||
    static auto instance = std::make_shared<TcpModuleMakePtr>();
 | 
			
		||||
    if (impl) {
 | 
			
		||||
        instance = *impl;
 | 
			
		||||
    }
 | 
			
		||||
    return instance;
 | 
			
		||||
}
 | 
			
		||||
std::shared_ptr<ITcpServer> *TcpModuleMakePtr::CreateTcpServer(const TcpParam param)
 | 
			
		||||
{
 | 
			
		||||
    return NewTcpServer(param);
 | 
			
		||||
}
 | 
			
		||||
std::shared_ptr<ITcpClient> *TcpModuleMakePtr::CreateTcpClient(const TcpParam param)
 | 
			
		||||
{
 | 
			
		||||
    return NewTcpClient(param);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										31
									
								
								utils/TcpModule/src/TcpModuleMakePtr.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								utils/TcpModule/src/TcpModuleMakePtr.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,31 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2023 Fancy Code.
 | 
			
		||||
 * 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 TCP_MODULE_MAKE_PTR_H
 | 
			
		||||
#define TCP_MODULE_MAKE_PTR_H
 | 
			
		||||
#include "StatusCode.h"
 | 
			
		||||
#include "TcpModule.h"
 | 
			
		||||
#include "ITcpServer.h"
 | 
			
		||||
#include "ITcpClient.h"
 | 
			
		||||
#include <memory>
 | 
			
		||||
class TcpModuleMakePtr
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    TcpModuleMakePtr() = default;
 | 
			
		||||
    virtual ~TcpModuleMakePtr() = default;
 | 
			
		||||
    static std::shared_ptr<TcpModuleMakePtr> &GetInstance(std::shared_ptr<TcpModuleMakePtr> *impl = nullptr);
 | 
			
		||||
    virtual std::shared_ptr<ITcpServer> *CreateTcpServer(const TcpParam param);
 | 
			
		||||
    virtual std::shared_ptr<ITcpClient> *CreateTcpClient(const TcpParam param);
 | 
			
		||||
};
 | 
			
		||||
#endif // !TCP_MODULE_MAKE_PTR_H
 | 
			
		||||
							
								
								
									
										45
									
								
								utils/TcpModule/src/TcpServerHandle.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								utils/TcpModule/src/TcpServerHandle.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,45 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2023 Fancy Code.
 | 
			
		||||
 * 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 "TcpServerHandle.h"
 | 
			
		||||
#include "ILog.h"
 | 
			
		||||
std::shared_ptr<TcpServerHandle> &TcpServerHandle::GetInstance(std::shared_ptr<TcpServerHandle> *impl)
 | 
			
		||||
{
 | 
			
		||||
    static auto instance = std::make_shared<TcpServerHandle>();
 | 
			
		||||
    if (impl) {
 | 
			
		||||
        if (instance.use_count() == 1) {
 | 
			
		||||
            LogInfo("Instance changed succeed.\n");
 | 
			
		||||
            instance = *impl;
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            LogError("Can't changing the instance becase of using by some one.\n");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return instance;
 | 
			
		||||
}
 | 
			
		||||
void TcpServerHandle::AddServer(const int &fd, const std::shared_ptr<ITcpServer> &server)
 | 
			
		||||
{
 | 
			
		||||
    LogInfo("AddServer fd = %d\n", fd);
 | 
			
		||||
    mFd[fd] = server;
 | 
			
		||||
}
 | 
			
		||||
bool TcpServerHandle::GetServer(const int &fd, std::shared_ptr<ITcpServer> &server)
 | 
			
		||||
{
 | 
			
		||||
    auto it = mFd.find(fd);
 | 
			
		||||
    if (it != mFd.end()) {
 | 
			
		||||
        server = it->second;
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    LogError("There no ITcpServer fd = %d\n", fd);
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -11,4 +11,22 @@
 | 
			
		|||
 * 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 TCP_SERVER_HANDLE_H
 | 
			
		||||
#define TCP_SERVER_HANDLE_H
 | 
			
		||||
#include "ITcpServer.h"
 | 
			
		||||
#include <map>
 | 
			
		||||
#include <memory>
 | 
			
		||||
class TcpServerHandle
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    TcpServerHandle() = default;
 | 
			
		||||
    ~TcpServerHandle() = default;
 | 
			
		||||
    static std::shared_ptr<TcpServerHandle> &GetInstance(std::shared_ptr<TcpServerHandle> *impl = nullptr);
 | 
			
		||||
    void AddServer(const int &fd, const std::shared_ptr<ITcpServer> &server);
 | 
			
		||||
    bool GetServer(const int &fd, std::shared_ptr<ITcpServer> &server);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    std::map<int, std::shared_ptr<ITcpServer>> mFd;
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										233
									
								
								utils/TcpModule/src/TcpServerImpl.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										233
									
								
								utils/TcpModule/src/TcpServerImpl.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,233 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2023 Fancy Code.
 | 
			
		||||
 * 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 "TcpServerImpl.h"
 | 
			
		||||
#include "ILog.h"
 | 
			
		||||
#include "TcpServerHandle.h"
 | 
			
		||||
static bool TcpClientAcceptObjectCheck(void *object)
 | 
			
		||||
{
 | 
			
		||||
    if (nullptr == object) {
 | 
			
		||||
        LogError("nullptr object!\n");
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    if (*((const char **)(((char *)object) - sizeof(ITcpServerHeader))) != GetTcpClientAcceptName()) {
 | 
			
		||||
        LogError("Illegal object!\n");
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
static void on_close(hio_t *io)
 | 
			
		||||
{
 | 
			
		||||
    LogInfo("on_close fd=%d error=%d\n", hio_fd(io), hio_error(io));
 | 
			
		||||
    // std::shared_ptr<ITcpServer> server;
 | 
			
		||||
    // if (TcpServerHandle::GetInstance()->GetServer(hio_fd(io), server) == true) {
 | 
			
		||||
    //     std::shared_ptr<TcpServerImpl> impl = std::dynamic_pointer_cast<TcpServerImpl>(server);
 | 
			
		||||
    //     if (impl != nullptr) {
 | 
			
		||||
    //         impl->ClosedEvent();
 | 
			
		||||
    //     }
 | 
			
		||||
    // }
 | 
			
		||||
}
 | 
			
		||||
static void on_recv(hio_t *io, void *buf, int readbytes)
 | 
			
		||||
{
 | 
			
		||||
    LogInfo("on_recv fd=%d readbytes=%d\n", hio_fd(io), readbytes);
 | 
			
		||||
    char localaddrstr[SOCKADDR_STRLEN] = {0};
 | 
			
		||||
    char peeraddrstr[SOCKADDR_STRLEN] = {0};
 | 
			
		||||
    LogInfo(
 | 
			
		||||
        "[%s] <=> [%s]\n", SOCKADDR_STR(hio_localaddr(io), localaddrstr), SOCKADDR_STR(hio_peeraddr(io), peeraddrstr));
 | 
			
		||||
    LogInfo("< %.*s", readbytes, (char *)buf);
 | 
			
		||||
    ITcpClientAccept *client = (ITcpClientAccept *)hevent_userdata(io);
 | 
			
		||||
    client->Readed((const char *)buf, readbytes);
 | 
			
		||||
    // server->RemoveClient(hio_fd(io));
 | 
			
		||||
    // std::shared_ptr<ITcpServer> server;
 | 
			
		||||
    // if (TcpServerHandle::GetInstance()->GetServer(hio_fd(io), server) == true) {
 | 
			
		||||
    //     std::shared_ptr<TcpServerImpl> impl = std::dynamic_pointer_cast<TcpServerImpl>(server);
 | 
			
		||||
    //     if (impl != nullptr) {
 | 
			
		||||
    //         impl->TcpServerReaded(buf, readbytes);
 | 
			
		||||
    //     }
 | 
			
		||||
    // }
 | 
			
		||||
    // echo
 | 
			
		||||
    // LogInfo("> %.*s", readbytes, (char *)buf);
 | 
			
		||||
    // hio_write(io, buf, readbytes);
 | 
			
		||||
}
 | 
			
		||||
static void on_accept(hio_t *io)
 | 
			
		||||
{
 | 
			
		||||
    LogInfo("on_accept connfd=%d\n", hio_fd(io));
 | 
			
		||||
    char localaddrstr[SOCKADDR_STRLEN] = {0};
 | 
			
		||||
    char peeraddrstr[SOCKADDR_STRLEN] = {0};
 | 
			
		||||
    LogInfo("accept connfd=%d [%s] <= [%s]\n",
 | 
			
		||||
            hio_fd(io),
 | 
			
		||||
            SOCKADDR_STR(hio_localaddr(io), localaddrstr),
 | 
			
		||||
            SOCKADDR_STR(hio_peeraddr(io), peeraddrstr));
 | 
			
		||||
 | 
			
		||||
    hio_setcb_close(io, on_close);
 | 
			
		||||
    hio_setcb_read(io, on_recv);
 | 
			
		||||
    std::shared_ptr<ITcpClientAccept> *client = NewTcpClientAccept(io);
 | 
			
		||||
    TcpServerImpl *server = (TcpServerImpl *)hevent_userdata(io);
 | 
			
		||||
    // std::shared_ptr<ITcpServer> server;
 | 
			
		||||
    // if (TcpServerHandle::GetInstance()->GetServer(hio_fd(io), server) == true) {
 | 
			
		||||
    //     std::shared_ptr<TcpServerImpl> impl = std::dynamic_pointer_cast<TcpServerImpl>(server);
 | 
			
		||||
    //     if (impl != nullptr) {
 | 
			
		||||
    //         impl->SetIo(io);
 | 
			
		||||
    //     }
 | 
			
		||||
    // }
 | 
			
		||||
    server->AddClient(io, client);
 | 
			
		||||
    hevent_set_userdata(io, (*client).get());
 | 
			
		||||
    hio_read_start(io);
 | 
			
		||||
}
 | 
			
		||||
TcpClientAcceptImpl::TcpClientAcceptImpl(const hio_t *io) : mIo(io)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
void TcpClientAcceptImpl::Readed(const void *data, size_t length)
 | 
			
		||||
{
 | 
			
		||||
    LogInfo("TcpClientAcceptImpl::Readed\n");
 | 
			
		||||
}
 | 
			
		||||
TcpServerImpl::TcpServerImpl(const TcpParam param) : mParam(param)
 | 
			
		||||
{
 | 
			
		||||
    mLoop = nullptr;
 | 
			
		||||
    mIo = nullptr;
 | 
			
		||||
}
 | 
			
		||||
void TcpServerImpl::Init(void)
 | 
			
		||||
{
 | 
			
		||||
    constexpr int NO_FALGS = 0;
 | 
			
		||||
    mLoop = hloop_new(NO_FALGS);
 | 
			
		||||
    if (nullptr == mLoop) {
 | 
			
		||||
        LogError("hloop_new failed\n");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    hio_t *listenio = hloop_create_tcp_server(mLoop, mParam.mIp, mParam.mPort, on_accept);
 | 
			
		||||
    if (nullptr == listenio) {
 | 
			
		||||
        LogError("hloop_create_tcp_server failed\n");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    LogInfo("listenfd=%d\n", hio_fd(listenio));
 | 
			
		||||
    hevent_set_userdata(listenio, this);
 | 
			
		||||
    mIo = listenio;
 | 
			
		||||
    std::shared_ptr<ITcpServer> server = shared_from_this();
 | 
			
		||||
    // TcpServerHandle::GetInstance()->AddServer(hio_fd(listenio), server);
 | 
			
		||||
    std::shared_ptr<TcpServerImpl> impl = std::dynamic_pointer_cast<TcpServerImpl>(server);
 | 
			
		||||
    auto recvThread = [](std::shared_ptr<TcpServerImpl> tcpServer) {
 | 
			
		||||
        tcpServer->Loop();
 | 
			
		||||
    };
 | 
			
		||||
    mTcpServerThread = std::thread(recvThread, impl);
 | 
			
		||||
}
 | 
			
		||||
void TcpServerImpl::UnInit(void)
 | 
			
		||||
{
 | 
			
		||||
    LogInfo("UnInit TcpServerImpl\n");
 | 
			
		||||
    FreeClients();
 | 
			
		||||
    if (nullptr != mLoop) {
 | 
			
		||||
        LogInfo("Stop loop.\n");
 | 
			
		||||
        hloop_stop(mLoop);
 | 
			
		||||
    }
 | 
			
		||||
    if (mTcpServerThread.joinable()) {
 | 
			
		||||
        mTcpServerThread.join();
 | 
			
		||||
    }
 | 
			
		||||
    hloop_free(&mLoop);
 | 
			
		||||
    mLoop = nullptr;
 | 
			
		||||
    mIo = nullptr;
 | 
			
		||||
}
 | 
			
		||||
void TcpServerImpl::TcpServerReaded(const void *buf, size_t length)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
void TcpServerImpl::TcpServerWrite(const void *buf, size_t length)
 | 
			
		||||
{
 | 
			
		||||
    if (mIo) {
 | 
			
		||||
        hio_write(mIo, buf, length);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    LogError("mIo is null\n");
 | 
			
		||||
}
 | 
			
		||||
void TcpServerImpl::ClosedEvent(void)
 | 
			
		||||
{
 | 
			
		||||
    mLoop = nullptr;
 | 
			
		||||
    mIo = nullptr;
 | 
			
		||||
}
 | 
			
		||||
void TcpServerImpl::Loop(void)
 | 
			
		||||
{
 | 
			
		||||
    if (nullptr == mLoop) {
 | 
			
		||||
        LogError("mLoop is null\n");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    hloop_run(mLoop);
 | 
			
		||||
}
 | 
			
		||||
void TcpServerImpl::AddClient(hio_t *io, std::shared_ptr<ITcpClientAccept> *client)
 | 
			
		||||
{
 | 
			
		||||
    char localaddrstr[SOCKADDR_STRLEN] = {0};
 | 
			
		||||
    char peeraddrstr[SOCKADDR_STRLEN] = {0};
 | 
			
		||||
    LogInfo("accept connfd=%d [%s] <= [%s]\n",
 | 
			
		||||
            hio_fd(io),
 | 
			
		||||
            SOCKADDR_STR(hio_localaddr(io), localaddrstr),
 | 
			
		||||
            SOCKADDR_STR(hio_peeraddr(io), peeraddrstr));
 | 
			
		||||
    mClients[hio_fd(io)] = client;
 | 
			
		||||
    if (mParam.mAcceptClientFunc) {
 | 
			
		||||
        mParam.mAcceptClientFunc(client, peeraddrstr);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
void TcpServerImpl::FreeClients(void)
 | 
			
		||||
{
 | 
			
		||||
    for (auto &client : mClients) {
 | 
			
		||||
        if (nullptr != client.second) {
 | 
			
		||||
            // delete client.second;
 | 
			
		||||
            // client.second = nullptr;
 | 
			
		||||
            void *object = (void *)client.second;
 | 
			
		||||
            if (TcpClientAcceptObjectCheck(object) == true) {
 | 
			
		||||
                // (*(std::shared_ptr<ITcpClientAccept> *)object)->UnInit();
 | 
			
		||||
                (*(std::shared_ptr<ITcpClientAccept> *)object).reset();
 | 
			
		||||
                free(((char *)object) - sizeof(ITcpServerHeader)); // TODO: bug?
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    // for (auto it = mClients.begin(); it != mClients.end();) {
 | 
			
		||||
    //     // 检查指针是否为空
 | 
			
		||||
    //     if (it->second != nullptr) {
 | 
			
		||||
    //         // 释放 shared_ptr,这将减少引用计数
 | 
			
		||||
    //         it->second->reset();
 | 
			
		||||
    //         // 删除指针
 | 
			
		||||
    //         delete it->second;
 | 
			
		||||
    //         // 从 map 中删除条目
 | 
			
		||||
    //         it = mClients.erase(it);
 | 
			
		||||
    //     }
 | 
			
		||||
    //     else {
 | 
			
		||||
    //         // 指针为空,继续迭代
 | 
			
		||||
    //         ++it;
 | 
			
		||||
    //     }
 | 
			
		||||
    // }
 | 
			
		||||
}
 | 
			
		||||
std::shared_ptr<ITcpServer> *NewTcpServer(const TcpParam param)
 | 
			
		||||
{
 | 
			
		||||
    LogInfo("Create tcp server object.\n");
 | 
			
		||||
    TcpServer *impl = (TcpServer *)malloc(sizeof(TcpServer));
 | 
			
		||||
    if (nullptr == impl) {
 | 
			
		||||
        LogError("NewTcpServer::malloc failed.\n");
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    TcpServer tmp;
 | 
			
		||||
    memcpy((void *)impl, (void *)&tmp, sizeof(TcpServer));
 | 
			
		||||
    impl->mHeader.mCheckName = GetTcpServerModuleName();
 | 
			
		||||
    impl->mTcpServer = std::make_shared<TcpServerImpl>(param);
 | 
			
		||||
    return (std::shared_ptr<ITcpServer> *)(((char *)impl) + sizeof(ITcpServerHeader));
 | 
			
		||||
}
 | 
			
		||||
std::shared_ptr<ITcpClientAccept> *NewTcpClientAccept(const hio_t *io)
 | 
			
		||||
{
 | 
			
		||||
    LogInfo("Create tcp server object.\n");
 | 
			
		||||
    TcpClientAccept *impl = (TcpClientAccept *)malloc(sizeof(TcpClientAccept));
 | 
			
		||||
    if (nullptr == impl) {
 | 
			
		||||
        LogError("NewTcpServer::malloc failed.\n");
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    TcpClientAccept tmp;
 | 
			
		||||
    memcpy((void *)impl, (void *)&tmp, sizeof(TcpClientAccept));
 | 
			
		||||
    impl->mHeader.mCheckName = GetTcpClientAcceptName();
 | 
			
		||||
    impl->mTcpClientAccept = std::make_shared<TcpClientAcceptImpl>(io);
 | 
			
		||||
    return (std::shared_ptr<ITcpClientAccept> *)(((char *)impl) + sizeof(ITcpServerHeader));
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										57
									
								
								utils/TcpModule/src/TcpServerImpl.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								utils/TcpModule/src/TcpServerImpl.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,57 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2023 Fancy Code.
 | 
			
		||||
 * 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 TCP_SERVER_IMPL_H
 | 
			
		||||
#define TCP_SERVER_IMPL_H
 | 
			
		||||
#include "ITcpServer.h"
 | 
			
		||||
#include "TcpModule.h"
 | 
			
		||||
#include "hloop.h"
 | 
			
		||||
#include "hsocket.h"
 | 
			
		||||
#include "hssl.h"
 | 
			
		||||
#include <map>
 | 
			
		||||
#include <thread>
 | 
			
		||||
class TcpClientAcceptImpl : public ITcpClientAccept
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    TcpClientAcceptImpl(const hio_t *io);
 | 
			
		||||
    virtual ~TcpClientAcceptImpl() = default;
 | 
			
		||||
    void Readed(const void *data, size_t length) override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    const hio_t *mIo;
 | 
			
		||||
};
 | 
			
		||||
class TcpServerImpl : public ITcpServer, public std::enable_shared_from_this<TcpServerImpl>
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    TcpServerImpl(const TcpParam param);
 | 
			
		||||
    virtual ~TcpServerImpl() = default;
 | 
			
		||||
    void Init(void) override;
 | 
			
		||||
    void UnInit(void) override;
 | 
			
		||||
    void TcpServerReaded(const void *buf, size_t length);
 | 
			
		||||
    void TcpServerWrite(const void *buf, size_t length);
 | 
			
		||||
    void ClosedEvent(void);
 | 
			
		||||
    void Loop(void);
 | 
			
		||||
    void AddClient(hio_t *io, std::shared_ptr<ITcpClientAccept> *client);
 | 
			
		||||
    void FreeClients(void);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    hloop_t *mLoop;
 | 
			
		||||
    hio_t *mIo;
 | 
			
		||||
    const TcpParam mParam;
 | 
			
		||||
    std::thread mTcpServerThread;
 | 
			
		||||
    std::map<int, std::shared_ptr<ITcpClientAccept> *> mClients;
 | 
			
		||||
};
 | 
			
		||||
std::shared_ptr<ITcpServer> *NewTcpServer(const TcpParam param);
 | 
			
		||||
std::shared_ptr<ITcpClientAccept> *NewTcpClientAccept(const hio_t *io);
 | 
			
		||||
#endif
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user