From 1c46e8302061d708eaea313afaa9f1b972718bd1 Mon Sep 17 00:00:00 2001 From: aozhiwei Date: Sun, 2 Jun 2019 20:16:18 +0800 Subject: [PATCH] add ioloop tcpclient2 --- a8/ioloop.cc | 30 ++++++++++ a8/ioloop.h | 22 ++++++++ a8/tcpclient2.cc | 139 +++++++++++++++++++++++++++++++++++++++++++++++ a8/tcpclient2.h | 39 +++++++++++++ 4 files changed, 230 insertions(+) create mode 100644 a8/ioloop.cc create mode 100644 a8/ioloop.h create mode 100644 a8/tcpclient2.cc create mode 100644 a8/tcpclient2.h diff --git a/a8/ioloop.cc b/a8/ioloop.cc new file mode 100644 index 0000000..7e7c1ec --- /dev/null +++ b/a8/ioloop.cc @@ -0,0 +1,30 @@ +#include + +#include +#include + +#include +#include +#include +#include + +#include + +#include + +void IoLoop::Init() +{ + epoll_fd = ::epoll_create(10000); + assert(epoll_fd != a8::INVALID_FD); +} + +void IoLoop::UnInit() +{ + ::close(epoll_fd); + epoll_fd = a8::INVALID_FD; +} + +void IoLoop::Update() +{ + +} diff --git a/a8/ioloop.h b/a8/ioloop.h new file mode 100644 index 0000000..b32966e --- /dev/null +++ b/a8/ioloop.h @@ -0,0 +1,22 @@ +#ifndef A8_IOLOOP_H +#define A8_IOLOOP_H + +namespace a8 +{ + class IoLoop : public a8::Singleton + { + private: + IoLoop() {}; + friend class a8::Singleton; + + public: + void Init(); + void UnInit(); + void Update(); + + private: + volatile int epoll_fd = a8::INVALID_FD; + }; +} + +#endif diff --git a/a8/tcpclient2.cc b/a8/tcpclient2.cc new file mode 100644 index 0000000..e461d7b --- /dev/null +++ b/a8/tcpclient2.cc @@ -0,0 +1,139 @@ +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +const int MAX_RECV_BUFFERSIZE = 1024 * 10; + +namespace a8 +{ + TcpClient2::TcpClient2() + { + send_buffer_mutex_ = new std::mutex(); + send_cond_mutex_ = new std::mutex(); + send_cond_ = new std::condition_variable(); + } + + TcpClient2::~TcpClient2() + { + Close(); + delete send_buffer_mutex_; + send_buffer_mutex_ = nullptr; + delete send_cond_mutex_; + send_cond_mutex_ = nullptr; + delete send_cond_; + send_cond_ = nullptr; + } + + void TcpClient2::Open() + { + if (!IsActive()) { + SetActive(true); + } + } + + void TcpClient2::Close() + { + if (IsActive()) { + SetActive(false); + } + } + + bool TcpClient2::IsActive() + { + return socket_ != a8::INVALID_SOCKET; + } + + bool TcpClient2::Connected() + { + return connected_; + } + + void TcpClient2::SendBuff(const char* buff, unsigned int bufflen) + { + if (bufflen > 0) { + a8::SendQueueNode* p = (a8::SendQueueNode*)malloc(sizeof(a8::SendQueueNode)); + memset(p, 0, sizeof(SendQueueNode)); + p->buff = (char*)malloc(bufflen); + memmove(p->buff, buff, bufflen); + p->bufflen = bufflen; + send_buffer_mutex_->lock(); + if (bot_node_) { + bot_node_->next = p; + bot_node_ = p; + }else{ + top_node_ = p; + bot_node_ = p; + } + send_buffer_mutex_->unlock(); + NotifySendCond(); + } + } + + void TcpClient2::SetActive(bool active) + { + if (active) { + if (IsActive()) { + return; + } + } else { + ActiveStop(); + } + } + + bool TcpClient2::ActiveStart() + { + socket_ = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (INVALID_SOCKET == socket_) { + if (on_error) { + on_error(this, errno); + } + return false; + } + sockaddr_in sa; + memset(&sa, 0, sizeof(sa)); + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = inet_addr(remote_address.c_str()); + sa.sin_port = htons(remote_port); + if (::connect(socket_, (sockaddr*)&sa, sizeof(sa)) < 0) { + if (on_error) { + on_error(this, errno); + } + ::close(socket_); + socket_ = INVALID_SOCKET; + return false; + } + connected_ = true; + if (on_connect) { + on_connect(this); + } + return true; + } + + void TcpClient2::ActiveStop() + { + connected_ = false; + if (socket_ != INVALID_SOCKET) { + shutdown(socket_, 2); + ::close(socket_); + } + socket_ = INVALID_SOCKET; + } + + void TcpClient2::NotifySendCond() + { + std::unique_lock lk(*send_cond_mutex_); + send_cond_->notify_all(); + } + +} diff --git a/a8/tcpclient2.h b/a8/tcpclient2.h new file mode 100644 index 0000000..783b9cf --- /dev/null +++ b/a8/tcpclient2.h @@ -0,0 +1,39 @@ +#ifndef A8_TCPCLIENT2_H +#define A8_TCPCLIENT2_H + +namespace a8 +{ + class TcpClient2 + { + public: + std::function on_error; + std::function on_connect; + std::function on_disconnect; + std::function on_socketread; + std::string remote_address; + int remote_port = 0; + + TcpClient(); + virtual ~TcpClient(); + + void Open(); + void Close(); + bool IsActive(); + bool Connected(); + void SendBuff(const char* buff, unsigned int bufflen); + + private: + volatile int socket_ = a8::INVALID_SOCKET; + volatile bool connected_ = false; + SendQueueNode *top_node_ = nullptr; + SendQueueNode *bot_node_ = nullptr; + std::mutex *send_cond_mutex_ = nullptr; + std::condition_variable *send_cond_ = nullptr; + + void SetActive(bool active); + bool ActiveStart(); + void ActiveStop(); + }; +} + +#endif