mirror of
https://gitee.com/jiuyilian/embedded-framework.git
synced 2025-01-06 10:16:51 -05:00
Improve readme files and comments
This commit is contained in:
parent
f508c8bbd5
commit
5a33dbfc06
|
@ -31,3 +31,29 @@
|
|||
|
||||
* **TcpClientAcceptImpl.h/TcpClientAcceptImpl.cpp**:实现了ITcpClientAccept接口,处理客户端连接的接受和数据交换。
|
||||
|
||||
# 一些易混淆的点
|
||||
1. 客户端创建的套接字包含指定`目标的IP地址和端口号`(TcpClientImpl类中的init函数),服务器创建的套接字只包含`本机IP地址和监听端口`。
|
||||
|
||||
2. 在网络编程中,服务器通常会在一个监听端口上等待来自客户端的连接请求。当服务器接受到一个连接请求时,它会创建一个新的套接字(或文件描述符)来表示这个新建立的连接,并且通常会为这个新的连接设置一系列的事件回调函数。
|
||||
|
||||
3. 客户端实例(TcpClientImpl类对象)进行init操作时,会创建一个套接字并对目标服务器发出连接请求并启动事件循环(Loop函数),然后客户端实例会一直进行事件循环(监听是否有读写操作)直至连接关闭(Close函数)。
|
||||
|
||||
# 该模块的实现过程
|
||||
## 服务器端:
|
||||
1. 创建服务器端套接字:使用 hloop_create_tcp_server 函数创建一个新的 TCP 服务器端套接字,并指定要监听的 IP 地址和端口号。
|
||||
2. 设置回调函数:为服务器端套接字设置回调函数,包括:
|
||||
on_accept:当有新的客户端尝试连接时调用。
|
||||
on_close:当服务器端套接字关闭时调用。
|
||||
3. 启动事件循环:使用 hloop_run 启动服务器的事件循环,等待客户端的连接请求。
|
||||
4. 接受连接:在 on_accept 回调函数中,接受客户端的连接请求,并创建用于该连接的新套接字。
|
||||
5. 创建客户端接受对象:为新的客户端连接创建一个 TcpClientAcceptImpl 对象,并设置相应的回调函数。
|
||||
管理客户端连接:将新创建的客户端接受对象添加到管理容器中,以便跟踪和管理。
|
||||
## 客户端:
|
||||
1. 创建客户端套接字:使用 hio_create_socket 函数创建一个新的 TCP 客户端套接字。
|
||||
2. 设置回调函数:为客户端套接字设置回调函数,包括:
|
||||
on_connect:当连接成功建立时调用。
|
||||
on_close:当连接关闭时调用。
|
||||
on_message:当接收到服务器发送的数据时调用。
|
||||
3. 连接到服务器:使用 hio_connect 函数向服务器发起连接请求。
|
||||
4. 启动事件循环:使用 hloop_run 启动客户端的事件循环,等待连接结果和数据传输。
|
||||
5. 处理连接结果:在 on_connect 回调函数中处理连接结果,如果连接成功,可以开始发送和接收数据。
|
|
@ -26,7 +26,7 @@
|
|||
/**
|
||||
* @brief Called when data is received on a TCP connection.
|
||||
*
|
||||
* @param io Socket handle
|
||||
* @param io Client's socket
|
||||
* @param buf The transmitted data content
|
||||
* @param len Byte length of transmitted data
|
||||
*/
|
||||
|
@ -38,17 +38,18 @@ static void on_message(hio_t *io, void *buf, int len)
|
|||
}
|
||||
/**
|
||||
* @brief Called when TCP connection is established.
|
||||
* @param io Socket handle
|
||||
* @param io Client's socket
|
||||
*/
|
||||
static void on_connect(hio_t *io)
|
||||
{
|
||||
LogInfo("onconnect: connfd=%d\n", hio_fd(io));
|
||||
hio_setcb_read(io, on_message);
|
||||
/// Start a read operation. Read data if it arrives.
|
||||
hio_read(io);
|
||||
}
|
||||
/**
|
||||
* @brief Called when tcp connection is disconnected.
|
||||
* @param io Socket handle
|
||||
* @param io Client't socket
|
||||
*/
|
||||
static void on_close(hio_t *io)
|
||||
{
|
||||
|
@ -60,8 +61,8 @@ TcpClientImpl::TcpClientImpl(const TcpClientParam ¶m, const void *object) :
|
|||
{
|
||||
}
|
||||
/**
|
||||
* @brief Initialize TCP clients, create event loops, I/O objects, and set callback functions for connection and
|
||||
* closure.
|
||||
* @brief Create a socket and connect it, and start an event loop to listen to io object operations (read and write,
|
||||
* etc.)
|
||||
*/
|
||||
void TcpClientImpl::Init(void)
|
||||
{
|
||||
|
@ -72,6 +73,19 @@ void TcpClientImpl::Init(void)
|
|||
LogError("TcpClientImpl::Init hloop_new failed.\n");
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* @brief The client's socket, which is used to actively send connection requests to the server and handle related
|
||||
* I/O operations, has no listening function.
|
||||
* @param mLoop Event loop.
|
||||
* When I/O events (connection closed, connection successful, data readable, etc.) occur, the event loop will call
|
||||
* the corresponding callback function to handle them.
|
||||
*
|
||||
* @param mParam.mIp Server IP address
|
||||
* @param mParam.mPort Server port
|
||||
* @param HIO_TYPE_TCP TCP connection
|
||||
* @param HIO_CLIENT_SIDE Indicates that the socket will be used as a client.
|
||||
*
|
||||
*/
|
||||
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");
|
||||
|
@ -80,9 +94,9 @@ void TcpClientImpl::Init(void)
|
|||
hevent_set_userdata(io, this);
|
||||
/// Set the callback function of successful connection, and there is no connection operation.
|
||||
hio_setcb_connect(io, on_connect);
|
||||
/// Set the callback function to close the connection, and there is no connection operation.
|
||||
hio_setcb_close(io, on_close);
|
||||
/// Connection operation
|
||||
hio_connect(io);
|
||||
hio_connect(io); ///< Connection operation
|
||||
mIo = io;
|
||||
std::shared_ptr<TcpClientImpl> impl = std::dynamic_pointer_cast<TcpClientImpl>(shared_from_this());
|
||||
auto recvThread = [](std::shared_ptr<TcpClientImpl> tcpClient) {
|
||||
|
@ -91,7 +105,7 @@ void TcpClientImpl::Init(void)
|
|||
mTcpClientThread = std::thread(recvThread, impl);
|
||||
}
|
||||
/**
|
||||
* @brief De-initialize the TCP client, close the I/O object and wait for the receiving thread to end.
|
||||
* @brief De-initialize the TCP client, close the client't socket and wait for the event cycle to end.
|
||||
*/
|
||||
void TcpClientImpl::UnInit(void)
|
||||
{
|
||||
|
@ -104,6 +118,12 @@ void TcpClientImpl::UnInit(void)
|
|||
mTcpClientThread.join();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief Read the data sent by the server in tcp connection.
|
||||
*
|
||||
* @param data Data content sent by the server
|
||||
* @param length Byte length of data content sent by the server.
|
||||
*/
|
||||
void TcpClientImpl::Readed(const void *data, size_t length)
|
||||
{
|
||||
if (nullptr != mParam.mReadFunc) {
|
||||
|
@ -112,6 +132,13 @@ void TcpClientImpl::Readed(const void *data, size_t length)
|
|||
}
|
||||
LogError("mParam.mReadFunc is nullptr.\n");
|
||||
}
|
||||
/**
|
||||
* @brief The client writes data to the server, and the writing operation can only be performed in the connected state.
|
||||
*
|
||||
* @param buf Content of written data
|
||||
* @param bufLenght Byte length of written data
|
||||
* @return ssize_t
|
||||
*/
|
||||
ssize_t TcpClientImpl::Write(const void *buf, const size_t bufLenght)
|
||||
{
|
||||
std::lock_guard<std::mutex> locker(mMutex);
|
||||
|
@ -122,6 +149,10 @@ ssize_t TcpClientImpl::Write(const void *buf, const size_t bufLenght)
|
|||
/// Returns the byte length of a packet.If it fails, an error code is returned.
|
||||
return hio_write(mIo, buf, bufLenght);
|
||||
}
|
||||
/**
|
||||
* @brief Close the tcp connection and stop the event loop (reading and writing I/O objects).
|
||||
*
|
||||
*/
|
||||
void TcpClientImpl::Closed(void)
|
||||
{
|
||||
std::lock_guard<std::mutex> locker(mMutex);
|
||||
|
@ -157,15 +188,12 @@ std::shared_ptr<ITcpClient> *NewTcpClient(const TcpClientParam ¶m)
|
|||
return nullptr;
|
||||
}
|
||||
TcpClient tmp;
|
||||
/// Initialize impl with tmp
|
||||
memcpy((void *)impl, (void *)&tmp, sizeof(TcpClient));
|
||||
impl->mHeader.mCheckName = GetTcpClientModuleName();
|
||||
/**
|
||||
* @brief ObjectThis points to the first address of the impl and offsets the address by ITcpClientHeader bytes,
|
||||
* that is, skips the mHeader part of the impl.
|
||||
*/
|
||||
/// ObjectThis is actually a pointer to mTcpClient in the TcpClient structure.
|
||||
std::shared_ptr<ITcpClient> *objectThis =
|
||||
(std::shared_ptr<ITcpClient> *)(((char *)impl) + sizeof(ITcpClientHeader));
|
||||
impl->mTcpClient = std::make_shared<TcpClientImpl>(param, objectThis);
|
||||
/// ObjectThis is used to verify whether the client is legal.
|
||||
return objectThis;
|
||||
}
|
|
@ -27,20 +27,21 @@ class TcpClientImpl : public ITcpClient, public std::enable_shared_from_this<Tcp
|
|||
public:
|
||||
TcpClientImpl(const TcpClientParam ¶m, const void *object);
|
||||
virtual ~TcpClientImpl() = default;
|
||||
void Init(void) override;
|
||||
void UnInit(void) override;
|
||||
void Readed(const void *data, size_t length) override;
|
||||
ssize_t Write(const void *buf, const size_t bufLenght) override;
|
||||
void Closed(void) override;
|
||||
void Init(void) override; ///< Create a socket and connect it, and start an event loop to listen to io object
|
||||
///< operations (read and write, etc.)
|
||||
void UnInit(void) override; ///< close the client't socket and wait for the event cycle to end.
|
||||
void Readed(const void *data, size_t length) override; ///< Read the data sent by the server in tcp connection.
|
||||
ssize_t Write(const void *buf, const size_t bufLenght) override; ///< client writes data to the server
|
||||
void Closed(void) override; ///< Close the tcp connection and stop the event loop (reading and writing I/O objects).
|
||||
void Loop(void);
|
||||
|
||||
private:
|
||||
std::mutex mMutex; /// A mutex lock used to synchronize access to shared resources.
|
||||
hloop_t *mLoop; /// Event loop, listening for io objects
|
||||
hio_t *mIo; /// Socket handle
|
||||
const TcpClientParam mParam; /// Basic information of the client, including port, ip, reading and closing.
|
||||
std::thread mTcpClientThread;
|
||||
const void *mObjectThis; /// ObjectThis is used to verify whether the client is legal.
|
||||
std::mutex mMutex; ///< A mutex lock used to synchronize access to shared resources.
|
||||
hloop_t *mLoop; ///< Event loop, Listen for read/write or connection closing operations.
|
||||
hio_t *mIo; ///< Client's socket
|
||||
const TcpClientParam mParam; ///< Basic information of the client, including port, ip, reading and closing.
|
||||
std::thread mTcpClientThread; ///< A separate thread that runs an event loop to receive and process network data
|
||||
const void *mObjectThis; ///< ObjectThis is used to verify whether the client is legal.
|
||||
};
|
||||
std::shared_ptr<ITcpClient> *NewTcpClient(const TcpClientParam ¶m);
|
||||
#endif
|
|
@ -25,9 +25,9 @@
|
|||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
/**
|
||||
* @brief Disconnect the connected client.
|
||||
* @brief Handle the close connection event.
|
||||
*
|
||||
* @param io Socket
|
||||
* @param io Server's socket
|
||||
*/
|
||||
static void on_close(hio_t *io)
|
||||
{
|
||||
|
@ -150,15 +150,13 @@ TcpServerImpl::TcpServerImpl(const TcpServerParam param) : mParam(param)
|
|||
void TcpServerImpl::Init(void)
|
||||
{
|
||||
constexpr int NO_FALGS = 0;
|
||||
/// Initialize event loop
|
||||
/// mLoop is used to manage all I/O objects and the events that occur on them.
|
||||
mLoop = hloop_new(NO_FALGS);
|
||||
if (nullptr == mLoop) {
|
||||
LogError("hloop_new failed\n");
|
||||
return;
|
||||
}
|
||||
/// Create a listening event to listen whether a new client sends a connection request.
|
||||
/// Listenio is part of mLoop.
|
||||
/// Create a socket to listen whether a new client sends a connection request.
|
||||
hio_t *listenio = hloop_create_tcp_server(mLoop, mParam.mIp, mParam.mPort, on_accept);
|
||||
if (nullptr == listenio) {
|
||||
LogError("hloop_create_tcp_server failed\n");
|
||||
|
@ -256,9 +254,9 @@ std::shared_ptr<ITcpClientAccept> *TcpServerImpl::GetClient(hio_t *io)
|
|||
return nullptr;
|
||||
}
|
||||
/**
|
||||
* @brief Remove the data element in the map, that is, the connected client.
|
||||
* @brief Removes a specific connection from the list of client connections maintained by the server.
|
||||
*
|
||||
* @param io Socket
|
||||
* @param io A server-side socket associated with an established client connection.
|
||||
*/
|
||||
void TcpServerImpl::RemoveClient(hio_t *io)
|
||||
{
|
||||
|
@ -316,6 +314,7 @@ std::shared_ptr<ITcpServer> *NewTcpServer(const TcpServerParam ¶m)
|
|||
return nullptr;
|
||||
}
|
||||
TcpServer tmp;
|
||||
/// Initialize impl with tmp
|
||||
memcpy((void *)impl, (void *)&tmp, sizeof(TcpServer));
|
||||
impl->mHeader.mCheckName = GetTcpServerModuleName();
|
||||
impl->mTcpServer = std::make_shared<TcpServerImpl>(param);
|
||||
|
|
|
@ -54,7 +54,7 @@ public:
|
|||
virtual ~TcpServerImpl() = default;
|
||||
void Init(void) override;
|
||||
void UnInit(void) override;
|
||||
void Loop(void); /// Run an event loop and release resources after completion or error.
|
||||
void Loop(void); /// Run an event loop and release resources after completion or error.
|
||||
void AddClient(hio_t *io);
|
||||
std::shared_ptr<ITcpClientAccept> *GetClient(hio_t *io);
|
||||
void RemoveClient(hio_t *io); /// Remove the data element in the map, that is, the connected client.
|
||||
|
@ -64,7 +64,7 @@ public:
|
|||
private:
|
||||
std::mutex mMutex; /// A mutex lock used to synchronize access to shared resources.
|
||||
hloop_t *mLoop; /// Event loop, listening for all io objects
|
||||
hio_t *mIo; /// listen whether a new client sends a connection request.
|
||||
hio_t *mIo; /// A server socket to listen whether a new client sends a connection request.
|
||||
const TcpServerParam mParam;
|
||||
std::thread mTcpServerThread;
|
||||
std::map<int, std::shared_ptr<ITcpClientAccept> *> mClients;
|
||||
|
|
Loading…
Reference in New Issue
Block a user