superdog/server/tcp_client.cpp

177 lines
4.7 KiB
C++

//
// Created by 29019 on 2020/4/18.
//
#define _WSPIAPI_H_
#define _WINSOCKAPI_
#include "tcp_client.h"
#include <stdio.h>
#include <cstring>
#include <string.h>
static void conn_writecb(struct bufferevent *, void *);
static void conn_readcb(struct bufferevent *, void *);
static void conn_eventcb(struct bufferevent *, short, void *);
void delay(int ms);
int ThreadRun(TcpClientLibevent *p);
void conn_writecb(struct bufferevent *bev, void *user_data)
{
}
// 运行线程
int ThreadRun(TcpClientLibevent *p) {
if (nullptr != p) {
p->mStatus = TcpClientLibevent::UNCONNECTED;
int ret = p->Dispatch();
if (0 > ret){
}
while ((p->mStatus != TcpClientLibevent::UNCONNECTED ))
{
if (p->mStatus == TcpClientLibevent::FAIL) { //连接失败,如果有设置自动重连就一直重连
p->ConnectServer();
#ifdef _WIN32
Sleep(100);
#else
//todo linux版本sleep
#endif
}
ret = p->Dispatch();
}
}
p->mStatus = TcpClientLibevent::UNCONNECTED;
return 0;
}
void conn_readcb(struct bufferevent *bev, void *user_data)
{
TcpClientLibevent *server = (TcpClientLibevent*)user_data;
struct evbuffer *input = bufferevent_get_input(bev);
size_t sz = evbuffer_get_length(input);
if (sz > 0)
{
uint8_t *msg = new uint8_t[sz];
int ret = bufferevent_read(bev, msg, sz);
printf("%s\n", msg);
if(server->mObserver != nullptr){
}
server->mObserver->OnData(msg,ret);
delete[] msg;
}
}
void conn_eventcb(struct bufferevent *bev, short events, void *user_data)
{
TcpClientLibevent *p;
p = (TcpClientLibevent *)user_data;
if (events & BEV_EVENT_EOF) {
if (nullptr != p->mObserver)
p->mObserver->OnDisConnected();
if (p != nullptr)
p->mStatus = TcpClientLibevent::UNCONNECTED;
printf("Connection closed\n");
}
else if (events & BEV_EVENT_ERROR) {
printf("Got an error on the connection: %s\n", strerror(errno));
if (nullptr != p->mObserver)
p->mObserver->OnDisConnected();
p->mStatus = TcpClientLibevent::FAIL;
}
else if (events & BEV_EVENT_CONNECTED) {
printf("Connect succeed\n");
//客户端链接成功后,给服务器发送第一条消息
if (nullptr != p->mObserver)
p->mObserver->OnConnected();
if (p != nullptr)
p->mStatus = TcpClientLibevent::UNCONNECTED;
return;
}
bufferevent_free(bev);
}
void delay(int ms)
{
clock_t start = clock();
while (clock() - start < ms);
}
bool TcpClientLibevent::Connected() {
return (((mStatus != UNCONNECTED)&& (mStatus != FAIL) )?true : false);
}
TcpClientLibevent::TcpClientLibevent(std::string addrinfo, int port, TcpClientLibevent::TcpClientObserver *p) :
mStatus(UNCONNECTED),
mObserver(nullptr)
{
memset(&mSrv, 0, sizeof(mSrv));
#ifdef linux
mSrv.sin_addr.s_addr = inet_addr(addrinfo.c_str());
mSrv.sin_family = AF_INET;
#endif
#ifdef _WIN32
mSrv.sin_addr.S_un.S_addr = inet_addr(addrinfo.c_str());
mSrv.sin_family = AF_INET;
#endif
mSrv.sin_port = htons(port);
mBase = event_base_new();
if (!mBase)
{
printf("Could not initialize libevent\n");
}
#ifdef WIN32
evthread_use_windows_threads();
#else
evthread_use_pthreads();
#endif
ConnectServer();
this->mThread = new thread(ThreadRun,this);
this->mObserver = p;
}
int TcpClientLibevent::ConnectServer() {
printf("connect server\r\n");
evthread_make_base_notifiable(mBase);
bev = bufferevent_socket_new(mBase, -1,
BEV_OPT_CLOSE_ON_FREE | BEV_OPT_THREADSAFE);
if (nullptr == bev) {
this->mStatus = TcpClientLibevent::FAIL;
return - 1;
}
bufferevent_setcb(bev, conn_readcb, conn_writecb, conn_eventcb, this);
int flag = bufferevent_socket_connect(bev, (struct sockaddr *)&mSrv, sizeof(mSrv));
bufferevent_enable(bev, EV_READ | EV_WRITE);
if (-1 == flag) {
this->mStatus = TcpClientLibevent::FAIL;
bufferevent_free(bev);
bev = nullptr;
printf("Connect failed\n");
return -1;
}
this->mStatus = TcpClientLibevent::CONNECTED;
return 0;
}
int TcpClientLibevent::SetReconnect(bool reconn) {
this->mReConnect = reconn;
return 0;
}
int TcpClientLibevent::SetObserver(TcpClientLibevent::TcpClientObserver *ob) {
this->mObserver = ob;
return 0;
}
int TcpClientLibevent::Dispatch() {
return event_base_dispatch(mBase);;
}
int TcpClientLibevent::Close() {
event_base_free(mBase);
return 0;
}