// // Created by 29019 on 2020/4/18. // #define _WSPIAPI_H_ #define _WINSOCKAPI_ #include "tcp_client.h" #include #include #include 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; }