add ioloop tcpclient2

This commit is contained in:
aozhiwei 2019-06-02 20:16:18 +08:00
parent 4798b23d2f
commit 1c46e83020
4 changed files with 230 additions and 0 deletions

30
a8/ioloop.cc Normal file
View File

@ -0,0 +1,30 @@
#include <a8/a8.h>
#include <memory.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <sys/epoll.h>
#include <netinet/tcp.h>
#include <thread>
#include <a8/ioloop.h>
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()
{
}

22
a8/ioloop.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef A8_IOLOOP_H
#define A8_IOLOOP_H
namespace a8
{
class IoLoop : public a8::Singleton<IoLoop>
{
private:
IoLoop() {};
friend class a8::Singleton<IoLoop>;
public:
void Init();
void UnInit();
void Update();
private:
volatile int epoll_fd = a8::INVALID_FD;
};
}
#endif

139
a8/tcpclient2.cc Normal file
View File

@ -0,0 +1,139 @@
#include <string.h>
#include <mutex>
#include <condition_variable>
#include <thread>
#include <unistd.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <sys/epoll.h>
#include <netinet/tcp.h>
#include <a8/a8.h>
#include <a8/tcpclient2.h>
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<std::mutex> lk(*send_cond_mutex_);
send_cond_->notify_all();
}
}

39
a8/tcpclient2.h Normal file
View File

@ -0,0 +1,39 @@
#ifndef A8_TCPCLIENT2_H
#define A8_TCPCLIENT2_H
namespace a8
{
class TcpClient2
{
public:
std::function<void (a8::TcpClient*, int)> on_error;
std::function<void (a8::TcpClient*)> on_connect;
std::function<void (a8::TcpClient*)> on_disconnect;
std::function<void (a8::TcpClient*, char*, unsigned int)> 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