mirror of
https://gitee.com/jiuyilian/embedded-framework.git
synced 2025-01-06 10:16:51 -05:00
add some annotate
This commit is contained in:
parent
c1f5931454
commit
625e9aabb3
|
@ -25,15 +25,15 @@ typedef bool (*TcpAcceptClientFunction)(void *, const char *);
|
|||
typedef void (*SocketClosedFunction)(const void *);
|
||||
typedef struct client_accept_parm
|
||||
{
|
||||
const TcpReadFunction mReadFunc;
|
||||
const SocketClosedFunction mClosedFunc;
|
||||
const TcpReadFunction mReadFunc; /// This function is defined in the test file.
|
||||
const SocketClosedFunction mClosedFunc; /// This function is defined in the test file.
|
||||
} ClientAcceptParam;
|
||||
typedef struct tcp_server_parm
|
||||
{
|
||||
const char *mIp; /**Server ip */
|
||||
const int mPort; /**Server port */
|
||||
const TcpAcceptClientFunction mAcceptClientFunc;
|
||||
const ClientAcceptParam mClientAcceptParam;
|
||||
const char *mIp; /// Server ip
|
||||
const int mPort; /// Server port
|
||||
const TcpAcceptClientFunction mAcceptClientFunc; /// This function is defined in the test file.
|
||||
const ClientAcceptParam mClientAcceptParam; /// This function is defined in the test file.
|
||||
} TcpServerParam;
|
||||
typedef struct tcp_parm
|
||||
{
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# TCP模块
|
||||
这个项目实现了一个用于网络通信的TCP模块,提供了服务器和客户端功能。
|
||||
在网络编程中,套接字(socket)是一个用于网络通信的端点。在客户端和服务器模型中,客户端会创建一个套接字来与服务器建立连接,而服务器则监听来自客户端的连接请求。一旦连接建立,客户端和服务器就可以通过各自的套接字进行数据的发送和接收。
|
||||
|
||||
# 涉及的知识
|
||||
* 网络通信
|
||||
|
|
|
@ -34,7 +34,7 @@ public:
|
|||
typedef struct i_tcp_client_header
|
||||
{
|
||||
const char *mCheckName;
|
||||
} ITcpClientHeader;
|
||||
} ITcpClientHeader;
|
||||
typedef struct tcp_client
|
||||
{
|
||||
ITcpClientHeader mHeader;
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include <sys/types.h>
|
||||
/**
|
||||
* @brief Called when data is received on a TCP connection.
|
||||
*
|
||||
*
|
||||
* @param io Socket handle
|
||||
* @param buf The transmitted data content
|
||||
* @param len Byte length of transmitted data
|
||||
|
@ -60,12 +60,14 @@ 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 Initialize TCP clients, create event loops, I/O objects, and set callback functions for connection and
|
||||
* closure.
|
||||
*/
|
||||
void TcpClientImpl::Init(void)
|
||||
{
|
||||
constexpr int NO_FALGS = 0;
|
||||
mLoop = hloop_new(NO_FALGS); ///Initialize event loop
|
||||
/// Initialize event loop
|
||||
mLoop = hloop_new(NO_FALGS);
|
||||
if (nullptr == mLoop) {
|
||||
LogError("TcpClientImpl::Init hloop_new failed.\n");
|
||||
return;
|
||||
|
@ -76,9 +78,11 @@ void TcpClientImpl::Init(void)
|
|||
return;
|
||||
}
|
||||
hevent_set_userdata(io, this);
|
||||
hio_setcb_connect(io, on_connect);///Set the callback function of successful connection, and there is no connection operation.
|
||||
/// Set the callback function of successful connection, and there is no connection operation.
|
||||
hio_setcb_connect(io, on_connect);
|
||||
hio_setcb_close(io, on_close);
|
||||
hio_connect(io); ///Connection operation
|
||||
/// Connection operation
|
||||
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) {
|
||||
|
@ -115,7 +119,8 @@ ssize_t TcpClientImpl::Write(const void *buf, const size_t bufLenght)
|
|||
LogError("mIo is nullptr.\n");
|
||||
return TCP_MODULE_WRITE_ERROR;
|
||||
}
|
||||
return hio_write(mIo, buf, bufLenght); ///Returns the byte length of a packet.If it fails, an error code is returned.
|
||||
/// Returns the byte length of a packet.If it fails, an error code is returned.
|
||||
return hio_write(mIo, buf, bufLenght);
|
||||
}
|
||||
void TcpClientImpl::Closed(void)
|
||||
{
|
||||
|
@ -130,8 +135,8 @@ void TcpClientImpl::Closed(void)
|
|||
}
|
||||
}
|
||||
/**
|
||||
* @brief Run event loop
|
||||
*
|
||||
* @brief Run an event loop and release resources after completion or error.
|
||||
*
|
||||
*/
|
||||
void TcpClientImpl::Loop(void)
|
||||
{
|
||||
|
@ -155,11 +160,12 @@ std::shared_ptr<ITcpClient> *NewTcpClient(const TcpClientParam ¶m)
|
|||
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,
|
||||
* @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.
|
||||
*/
|
||||
std::shared_ptr<ITcpClient> *objectThis =
|
||||
(std::shared_ptr<ITcpClient> *)(((char *)impl) + sizeof(ITcpClientHeader));
|
||||
impl->mTcpClient = std::make_shared<TcpClientImpl>(param, objectThis);
|
||||
return objectThis; ///ObjectThis is used to verify whether the client is legal.
|
||||
/// ObjectThis is used to verify whether the client is legal.
|
||||
return objectThis;
|
||||
}
|
|
@ -35,12 +35,12 @@ public:
|
|||
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::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.
|
||||
const void *mObjectThis; /// ObjectThis is used to verify whether the client is legal.
|
||||
};
|
||||
std::shared_ptr<ITcpClient> *NewTcpClient(const TcpClientParam ¶m);
|
||||
#endif
|
|
@ -23,7 +23,7 @@
|
|||
#include <sys/types.h>
|
||||
/**
|
||||
* @brief Verify that object is a legitimate (existing) server.
|
||||
*
|
||||
*
|
||||
* @param object Save the address of the character pointer variable.
|
||||
* Should be substituted into the private member objectThis of the client instance.
|
||||
* If the value of the character pointer pointed by *object is "tcp_server", return turn
|
||||
|
@ -44,9 +44,9 @@ static bool TcpServerObjectCheck(void *object)
|
|||
}
|
||||
/**
|
||||
* @brief Verify that object is a legitimate (existing) client.
|
||||
*
|
||||
*
|
||||
* @param object Save the address of the character pointer variable.
|
||||
*
|
||||
*
|
||||
* @return true Indicates that the client exists.
|
||||
* @return false Indicates that the client does not exist
|
||||
*/
|
||||
|
|
|
@ -27,6 +27,7 @@ public:
|
|||
bool GetServer(const int &fd, std::shared_ptr<ITcpServer> &server);
|
||||
|
||||
private:
|
||||
/// Store multiple servers
|
||||
std::map<int, std::shared_ptr<ITcpServer>> mFd;
|
||||
};
|
||||
#endif
|
|
@ -24,18 +24,35 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
/**
|
||||
* @brief Disconnect the connected client.
|
||||
*
|
||||
* @param io Socket
|
||||
*/
|
||||
static void on_close(hio_t *io)
|
||||
{
|
||||
LogInfo("on_close fd=%d error=%d\n", hio_fd(io), hio_error(io));
|
||||
TcpServerImpl *server = (TcpServerImpl *)hevent_userdata(io);
|
||||
server->RemoveClient(io);
|
||||
}
|
||||
/**
|
||||
* @brief Close the port on which the server listens for client connections.
|
||||
*
|
||||
* @param io The port on which the server listens for client connections.
|
||||
*/
|
||||
static void server_on_close(hio_t *io)
|
||||
{
|
||||
LogInfo("server_on_close fd=%d error=%d\n", hio_fd(io), hio_error(io));
|
||||
TcpServerImpl *server = (TcpServerImpl *)hevent_userdata(io);
|
||||
server->Closed();
|
||||
}
|
||||
/**
|
||||
* @brief The server processes data
|
||||
*
|
||||
* @param io Socket
|
||||
* @param buf data
|
||||
* @param readbytes bytes
|
||||
*/
|
||||
static void on_recv(hio_t *io, void *buf, int readbytes)
|
||||
{
|
||||
LogInfo("on_recv fd=%d readbytes=%d\n", hio_fd(io), readbytes);
|
||||
|
@ -48,6 +65,11 @@ static void on_recv(hio_t *io, void *buf, int readbytes)
|
|||
std::shared_ptr<ITcpClientAccept> *client = server->GetClient(io);
|
||||
(*client)->Readed((const char *)buf, readbytes);
|
||||
}
|
||||
/**
|
||||
* @brief Handles a new accept client connection event
|
||||
*
|
||||
* @param io Socket for newly accepted client connection
|
||||
*/
|
||||
static void on_accept(hio_t *io)
|
||||
{
|
||||
LogInfo("on_accept connfd=%d\n", hio_fd(io));
|
||||
|
@ -63,12 +85,17 @@ static void on_accept(hio_t *io)
|
|||
// std::shared_ptr<ITcpClientAccept> *client = NewTcpClientAccept(io);
|
||||
TcpServerImpl *server = (TcpServerImpl *)hevent_userdata(io);
|
||||
server->AddClient(io);
|
||||
/// Set up a read event
|
||||
hio_read_start(io);
|
||||
}
|
||||
TcpClientAcceptImpl::TcpClientAcceptImpl(const hio_t *io, const void *object, const ClientAcceptParam ¶m)
|
||||
: mIo(io), mObjectThis(object), mParam(param)
|
||||
{
|
||||
}
|
||||
/**
|
||||
* @brief Disconnect the client
|
||||
*
|
||||
*/
|
||||
void TcpClientAcceptImpl::Close(void)
|
||||
{
|
||||
if (nullptr != mIo) {
|
||||
|
@ -76,14 +103,28 @@ void TcpClientAcceptImpl::Close(void)
|
|||
hio_close(io);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief The server reads the data received by tcp connection.
|
||||
*
|
||||
* @param data
|
||||
* @param length bytes
|
||||
*/
|
||||
void TcpClientAcceptImpl::Readed(const void *data, size_t length)
|
||||
{
|
||||
if (nullptr != mParam.mReadFunc) {
|
||||
mParam.mReadFunc(data, length, mObjectThis);
|
||||
return;
|
||||
}
|
||||
LogWarning("mParam.mClosedFunc is null\n");
|
||||
LogWarning("mParam.mReadedFunc is null\n");
|
||||
}
|
||||
/**
|
||||
* @brief The server writes data to the tcp connection.
|
||||
*
|
||||
* @param data Written data
|
||||
* @param length Byte length of written data
|
||||
* @return ssize_t
|
||||
* Returns the number of bytes written if the writing is successful, and returns the error code -1 if it fails.
|
||||
*/
|
||||
ssize_t TcpClientAcceptImpl::Write(const void *data, size_t length)
|
||||
{
|
||||
if (mIo) {
|
||||
|
@ -109,11 +150,15 @@ TcpServerImpl::TcpServerImpl(const TcpServerParam param) : mParam(param)
|
|||
void TcpServerImpl::Init(void)
|
||||
{
|
||||
constexpr int NO_FALGS = 0;
|
||||
mLoop = hloop_new(NO_FALGS); ///Initialize event loop
|
||||
/// 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.
|
||||
hio_t *listenio = hloop_create_tcp_server(mLoop, mParam.mIp, mParam.mPort, on_accept);
|
||||
if (nullptr == listenio) {
|
||||
LogError("hloop_create_tcp_server failed\n");
|
||||
|
@ -132,11 +177,17 @@ void TcpServerImpl::Init(void)
|
|||
};
|
||||
mTcpServerThread = std::thread(recvThread, impl);
|
||||
}
|
||||
/**
|
||||
* @brief De-initialize the TCP server, close the I/O object and wait for the receiving thread to end.
|
||||
*
|
||||
*/
|
||||
void TcpServerImpl::UnInit(void)
|
||||
{
|
||||
LogInfo("UnInit TcpServerImpl\n");
|
||||
/// Close all client connections
|
||||
FreeClients();
|
||||
if (nullptr != mIo) {
|
||||
/// Turn off connection monitoring
|
||||
hio_close(mIo);
|
||||
mIo = nullptr;
|
||||
}
|
||||
|
@ -144,6 +195,10 @@ void TcpServerImpl::UnInit(void)
|
|||
mTcpServerThread.join();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief Run an event loop and release resources after completion or error.
|
||||
*
|
||||
*/
|
||||
void TcpServerImpl::Loop(void)
|
||||
{
|
||||
if (nullptr == mLoop) {
|
||||
|
@ -154,6 +209,11 @@ void TcpServerImpl::Loop(void)
|
|||
hloop_free(&mLoop);
|
||||
mLoop = nullptr;
|
||||
}
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param io Add the socket of the newly connected client.
|
||||
*/
|
||||
void TcpServerImpl::AddClient(hio_t *io)
|
||||
{
|
||||
mMutex.lock();
|
||||
|
@ -165,6 +225,9 @@ void TcpServerImpl::AddClient(hio_t *io)
|
|||
SOCKADDR_STR(hio_peeraddr(io), peeraddrstr));
|
||||
std::shared_ptr<ITcpClientAccept> *addClient = NewTcpClientAccept(io, mParam.mClientAcceptParam);
|
||||
mClients[hio_fd(io)] = addClient;
|
||||
/**
|
||||
* @brief Check whether the server side accepts the connection of the client side.
|
||||
*/
|
||||
if (mParam.mAcceptClientFunc) {
|
||||
if (mParam.mAcceptClientFunc(addClient, peeraddrstr) == true) {
|
||||
mMutex.unlock();
|
||||
|
@ -176,6 +239,12 @@ void TcpServerImpl::AddClient(hio_t *io)
|
|||
hio_close(io);
|
||||
LogWarning("AddClient failed.\n");
|
||||
}
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param io socket
|
||||
* @return std::shared_ptr<ITcpClientAccept>*
|
||||
*/
|
||||
std::shared_ptr<ITcpClientAccept> *TcpServerImpl::GetClient(hio_t *io)
|
||||
{
|
||||
std::lock_guard<std::mutex> locker(mMutex);
|
||||
|
@ -186,6 +255,11 @@ std::shared_ptr<ITcpClientAccept> *TcpServerImpl::GetClient(hio_t *io)
|
|||
LogError("GetClient failed, client not exit.\n");
|
||||
return nullptr;
|
||||
}
|
||||
/**
|
||||
* @brief Remove the data element in the map, that is, the connected client.
|
||||
*
|
||||
* @param io Socket
|
||||
*/
|
||||
void TcpServerImpl::RemoveClient(hio_t *io)
|
||||
{
|
||||
std::lock_guard<std::mutex> locker(mMutex);
|
||||
|
@ -203,6 +277,10 @@ void TcpServerImpl::RemoveClient(hio_t *io)
|
|||
LogError("RemoveClient failed, client not exit.\n");
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief Clear all connected clients.
|
||||
*
|
||||
*/
|
||||
void TcpServerImpl::FreeClients(void)
|
||||
{
|
||||
std::lock_guard<std::mutex> locker(mMutex);
|
||||
|
@ -218,6 +296,10 @@ void TcpServerImpl::FreeClients(void)
|
|||
}
|
||||
mClients.clear();
|
||||
}
|
||||
/**
|
||||
* @brief Stop listening to the event loop
|
||||
*
|
||||
*/
|
||||
void TcpServerImpl::Closed(void)
|
||||
{
|
||||
if (nullptr != mLoop) {
|
||||
|
|
|
@ -22,6 +22,11 @@
|
|||
#include <map>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
/**
|
||||
* @brief The server manages the connection life cycle and data interaction of each connected client through this kind
|
||||
* of instance.
|
||||
*
|
||||
*/
|
||||
class TcpClientAcceptImpl : public ITcpClientAccept, public std::enable_shared_from_this<TcpClientAcceptImpl>
|
||||
{
|
||||
public:
|
||||
|
@ -33,10 +38,15 @@ public:
|
|||
void Closed(void) override;
|
||||
|
||||
private:
|
||||
const hio_t *mIo;
|
||||
const hio_t *mIo; /// Connected client socket
|
||||
const void *mObjectThis;
|
||||
const ClientAcceptParam mParam;
|
||||
};
|
||||
/**
|
||||
* @brief The TcpServerImpl class is responsible for listening to connection requests from clients and creating an
|
||||
* instance of TcpClientAcceptImpl for each accepted connection.
|
||||
*
|
||||
*/
|
||||
class TcpServerImpl : public ITcpServer, public std::enable_shared_from_this<TcpServerImpl>
|
||||
{
|
||||
public:
|
||||
|
@ -44,17 +54,17 @@ public:
|
|||
virtual ~TcpServerImpl() = default;
|
||||
void Init(void) override;
|
||||
void UnInit(void) override;
|
||||
void Loop(void);
|
||||
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);
|
||||
void FreeClients(void);
|
||||
void Closed(void);
|
||||
void RemoveClient(hio_t *io); /// Remove the data element in the map, that is, the connected client.
|
||||
void FreeClients(void); /// Clear all connected clients.
|
||||
void Closed(void); /// Stop listening to the event loop(mLoop)
|
||||
|
||||
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
|
||||
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.
|
||||
const TcpServerParam mParam;
|
||||
std::thread mTcpServerThread;
|
||||
std::map<int, std::shared_ptr<ITcpClientAccept> *> mClients;
|
||||
|
|
Loading…
Reference in New Issue
Block a user