int main(int argc, char* argv[]) { signal(SIGINT, signalFun); if (argc == 2 && (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "/?") == 0)) { cout << "please input like example:" << endl; cout << "tcpTest remoteIP remotePort startType" << endl; cout << "./tcpTest 0.0.0.0 8081 0" << endl; cout << "startType: 0 server, 1 client" << endl; return 0; } if (argc > 1) g_remoteIP = argv[1]; if (argc > 2) g_remotePort = atoi(argv[2]); if (argc > 3) g_startType = atoi(argv[3]); if (g_startType == 0) ILog4zManager::getPtr()->config("server.cfg"); else ILog4zManager::getPtr()->config("client.cfg"); ILog4zManager::getPtr()->start(); LOGI("g_remoteIP=" << g_remoteIP << ", g_remotePort=" << g_remotePort << ", g_startType=" << g_startType ); summer = std::shared_ptr<EventLoop>(new EventLoop); summer->initialize(); if (g_startType == 0) { accepter = std::shared_ptr<TcpAccept>(new TcpAccept()); accepter->initialize(summer); ts = std::shared_ptr<TcpSocket>(new TcpSocket); if (!accepter->openAccept(g_remoteIP.c_str(), g_remotePort)) return 0; accepter->doAccept(ts, std::bind(OnAcceptSocket, std::placeholders::_1, std::placeholders::_2)); } else { usedSocket = std::shared_ptr<TcpSocket>(new TcpSocket); usedSocket->initialize(summer); usedSocket->doConnect(g_remoteIP.c_str(), g_remotePort, std::bind(onConnect, std::placeholders::_1)); } std::function<void()> moniter = [&moniter]() { cout << "echo=" << sendCount / 5 << endl; sendCount = 0; summer->createTimer(5000, std::bind(moniter)); }; summer->createTimer(5000, std::bind(moniter)); while (g_runing) summer->runOnce(); ts.reset(); accepter.reset(); usedSocket.reset(); return 0; }
void OnSocketRecv(NetErrorCode ec, int recvLength) { if (ec != NEC_SUCCESS) return; memcpy(sendBuffer, recvBuffer, recvLength); sendBufferLen = recvLength; bool ret = usedSocket->doSend(sendBuffer, sendBufferLen, std::bind(OnSocketSend, std::placeholders::_1, std::placeholders::_2));// safe-warning: can't call this method again when last doSend request not return. if (!ret) return; ret = usedSocket->doRecv(recvBuffer, recvBufferLen, std::bind(OnSocketRecv, std::placeholders::_1, std::placeholders::_2)); if (!ret) return; sendCount++; };
void OnAcceptSocket(NetErrorCode ec, TcpSocketPtr s) { if (ec != NEC_SUCCESS) { g_runing = false; return; } usedSocket = s; usedSocket->initialize(summer); usedSocket->doRecv(recvBuffer, recvBufferLen, std::bind(OnSocketRecv, std::placeholders::_1, std::placeholders::_2)); };
void OnAcceptSocket(NetErrorCode ec, TcpSocketPtr s) { if (ec != NEC_SUCCESS) { g_runing = false; return; } usedSocket = s; usedSocket->initialize(summer); usedSocket->doRecv(recvBuffer, recvBufferLen, std::bind(OnServerSocketRecv, std::placeholders::_1, std::placeholders::_2)); ts = std::shared_ptr<TcpSocket>(new TcpSocket); accepter->doAccept(ts, std::bind(OnAcceptSocket, std::placeholders::_1, std::placeholders::_2)); };
void onConnect(NetErrorCode ec) { if (ec != NEC_SUCCESS) { LOGE("connect error"); g_runing = false; return; } usedSocket->doRecv(recvBuffer, recvBufferLen, std::bind(OnSocketRecv, std::placeholders::_1, std::placeholders::_2)); sprintf(sendBuffer, "%s", "hellow----------------------------------------------------------"); sendBufferLen = (int)strlen(sendBuffer) + 1; usedSocket->doSend(sendBuffer, sendBufferLen, std::bind(OnSocketSend, std::placeholders::_1, std::placeholders::_2));// safe-warning: one socket can't concurrent call this method without wait callback. };
bool TcpSession::attatch(const TcpSocketPtr &sockptr, AccepterID aID, SessionID sID) { _sockptr = sockptr; _acceptID = aID; _sessionID = sID; _sockptr->getPeerInfo(_remoteIP, _remotePort); if (_options._setNoDelay) { sockptr->setNoDelay(); } _status = 2; _pulseTimerID = SessionManager::getRef().createTimer(_options._sessionPulseInterval, std::bind(&TcpSession::onPulse, shared_from_this())); SessionManager::getRef()._statInfo[STAT_SESSION_LINKED]++; if (_options._onSessionLinked) { _options._onSessionLinked(shared_from_this()); } if (!doRecv()) { close(); return false; } return true; }
bool NetResMgr::AsyncTcpAccept(TcpHandle handle, const TcpSocketPtr& socket, std::unique_ptr<tcp::AcceptBuffer> buffer) { auto accept_socket = std::make_unique<tcp::Socket>(); if (!accept_socket) { LOG(kError, "AsyncTcpAccept failed: can not new tcp socket."); return false; } if (!accept_socket->Create()) { return false; } if (!buffer) { buffer = std::make_unique<tcp::AcceptBuffer>(); if (!buffer) { LOG(kError, "AsyncTcpAccept failed: can not new accept buffer."); return false; } } auto async_sock = accept_socket->socket(); buffer->Reset(); buffer->set_handle(handle); buffer->set_accept_socket(std::move(accept_socket)); if (!socket->AsyncAccept(async_sock, buffer->buffer(), buffer->buffer_size(), buffer->ovlp())) { return false; } buffer.release(); return true; }
void doClose() { if (usedSocket) { usedSocket->doClose();//safe method need wait callback, at this example ignore the safe method. } g_runing = false; }
BsdClientTransport::BsdClientTransport(TcpSocketPtr socketPtr) : mFd(-1), mTcpSocketPtr(socketPtr), mpIoService(& socketPtr->get_io_service()), mWriteCounter(0) { mClosed = false; mAsioTimerPtr.reset( new AsioDeadlineTimer( getAmiThreadPool().getIoService() )); }
void SendOneMsg() { if (usedSocket && summer && g_runing) { sprintf(sendBuffer, "%s", "hellow"); sendBufferLen = (int)strlen(sendBuffer) + 1; usedSocket->doSend(sendBuffer, sendBufferLen, std::bind(OnSocketSend, std::placeholders::_1, std::placeholders::_2));// safe-warning: one socket can't concurrent call this method without wait callback. } }
void OnServerSocketRecv(NetErrorCode ec, int recvLength) { if (ec != NEC_SUCCESS) { return; } LOGI("recv client msg len = " << recvLength << ", msg :" << recvBuffer); memcpy(sendBuffer, recvBuffer, recvLength); sendBufferLen = recvLength; bool ret = usedSocket->doSend(sendBuffer, sendBufferLen, std::bind(OnSocketSend, std::placeholders::_1, std::placeholders::_2));// safe-warning: can't call this method again when last doSend request not return. if (!ret) { return; } ret = usedSocket->doRecv(recvBuffer, recvBufferLen, std::bind(OnServerSocketRecv, std::placeholders::_1, std::placeholders::_2)); if (!ret) { return; } };
void onConnect(NetErrorCode ec) { if (ec != NEC_SUCCESS) { LOGE("connect error"); g_runing = false; return; } usedSocket->doRecv(recvBuffer, recvBufferLen, std::bind(OnClientSocektRecv, std::placeholders::_1, std::placeholders::_2)); summer->createTimer(1000, std::bind(SendOneMsg)); };
void OnClientSocektRecv(NetErrorCode ec, int recvLength) { if (ec != NEC_SUCCESS) { g_runing = false; return; } LOGI("recv server msg len = " << recvLength << ", msg :" << recvBuffer); summer->createTimer(1000, std::bind(SendOneMsg)); bool ret = usedSocket->doRecv(recvBuffer, recvBufferLen, std::bind( OnClientSocektRecv, std::placeholders::_1, std::placeholders::_2)); if (!ret) { g_runing = false; return; }; };
bool NetResMgr::AsyncTcpRecv(TcpHandle handle, const TcpSocketPtr& socket, std::unique_ptr<tcp::RecvBuffer> buffer) { if (!buffer) { buffer = std::make_unique<tcp::RecvBuffer>(); if (!buffer) { LOG(kError, "AsyncTcpRecv failed: can not new recv buffer."); return false; } } buffer->Reset(); buffer->set_handle(handle); if (!socket->AsyncRecv(buffer->buffer(), buffer->buffer_size(), buffer->ovlp())) { return false; } buffer.release(); return true; }
void SessionManager::onAcceptNewClient(zsummer::network::NetErrorCode ec, const TcpSocketPtr& s, const TcpAcceptPtr &accepter, AccepterID aID) { if (!_running || ! _openAccept) { LCI("shutdown accepter. aID=" << aID); return; } auto iter = _mapAccepterConfig.find(aID); if (iter == _mapAccepterConfig.end()) { LCE("Unknown AccepterID aID=" << aID); return; } if (ec) { LCE("doAccept Result Error. ec=" << ec << ", traits=" << iter->second.first); TcpSocketPtr newclient(new zsummer::network::TcpSocket); newclient->initialize(_summer); auto &&handler = std::bind(&SessionManager::onAcceptNewClient, this, std::placeholders::_1, std::placeholders::_2, accepter, aID); auto timer = [accepter, newclient, handler]() { accepter->doAccept(newclient, std::move(handler)); }; createTimer(5000, std::move(timer)); return; } std::string remoteIP; unsigned short remotePort = 0; s->getPeerInfo(remoteIP, remotePort); //! check white list //! --------------------- if (!iter->second.first._whitelistIP.empty()) { bool checkSucess = false; for (auto white : iter->second.first._whitelistIP) { if (remoteIP.size() >= white.size()) { if (remoteIP.compare(0,white.size(), white) == 0) { checkSucess = true; break; } } } if (!checkSucess) { LCW("Accept New Client Check Whitelist Failed remoteAdress=" << remoteIP << ":" << remotePort << ", trais=" << iter->second.first); TcpSocketPtr newclient(new zsummer::network::TcpSocket); newclient->initialize(_summer); accepter->doAccept(newclient, std::bind(&SessionManager::onAcceptNewClient, this, std::placeholders::_1, std::placeholders::_2, accepter, aID)); return; } else { LCI("Accept New Client Check Whitelist Success remoteAdress=" << remoteIP << ":" << remotePort << ", trais=" << iter->second.first); } } //! check Max Sessions if (iter->second.second._currentLinked >= iter->second.first._maxSessions) { LCW("Accept New Client. Too Many Sessions And The new socket will closed. remoteAddress=" << remoteIP << ":" << remotePort << ", Aready linked sessions = " << iter->second.second._currentLinked << ", trais=" << iter->second.first); } else { LCD("Accept New Client. Accept new Sessions. The new socket remoteAddress=" << remoteIP << ":" << remotePort << ", Aready linked sessions = " << iter->second.second._currentLinked << ", trais=" << iter->second.first); iter->second.second._currentLinked++; iter->second.second._totalAcceptCount++; _lastSessionID = nextSessionID(_lastSessionID); TcpSessionPtr session(new TcpSession()); s->initialize(_summer); if (session->bindTcpSocketPrt(s, aID, _lastSessionID, iter->second.first)) { _mapTcpSessionPtr[_lastSessionID] = session; _totalAcceptCount++; MessageDispatcher::getRef().dispatchOnSessionEstablished(session); } } //! accept next socket. TcpSocketPtr newclient(new zsummer::network::TcpSocket); newclient->initialize(_summer); accepter->doAccept(newclient, std::bind(&SessionManager::onAcceptNewClient, this, std::placeholders::_1, std::placeholders::_2, accepter,aID)); }
int main(int argc, char* argv[]) { signal(SIGINT, signalFun); if (argc == 2 && (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "/?") == 0)) { cout << "please input like example:" << endl; cout << "tcpTest remoteIP remotePort startType" << endl; cout << "./tcpTest 0.0.0.0 8081 0" << endl; cout << "startType: 0 server, 1 client" << endl; return 0; } if (argc > 1) { g_remoteIP = argv[1]; } if (argc > 2) { g_remotePort = atoi(argv[2]); } if (argc > 3) { g_startType = atoi(argv[3]); } if (g_startType == 0) { ILog4zManager::getPtr()->config("server.cfg"); ILog4zManager::getPtr()->start(); } else { ILog4zManager::getPtr()->config("client.cfg"); ILog4zManager::getPtr()->start(); } LOGI("g_remoteIP=" << g_remoteIP << ", g_remotePort=" << g_remotePort << ", g_startType=" << g_startType ); summer = std::shared_ptr<EventLoop>(new EventLoop); summer->initialize(); if (g_startType == 0) { accepter = std::shared_ptr<TcpAccept>(new TcpAccept()); accepter->initialize(summer); ts = std::shared_ptr<TcpSocket>(new TcpSocket); if (!accepter->openAccept(g_remoteIP.c_str(), g_remotePort)) { return 0; } accepter->doAccept(ts, std::bind(OnAcceptSocket, std::placeholders::_1, std::placeholders::_2)); } else { usedSocket = std::shared_ptr<TcpSocket>(new TcpSocket); usedSocket->initialize(summer); usedSocket->doConnect(g_remoteIP.c_str(), g_remotePort, std::bind(onConnect, std::placeholders::_1)); } while (g_runing) { summer->runOnce(); } ts.reset(); accepter.reset(); usedSocket.reset(); //warning: be safe close need: 1.close all established socket. 2. wait all socket recv callback. 3 stop runonce and safe exit. return 0; }
void SessionManager::onAcceptNewClient(zsummer::network::NetErrorCode ec, const TcpSocketPtr& s, const TcpAcceptPtr &accepter, AccepterID aID) { if (!_running || _stopAccept) { LCI("shutdown accepter. aID=" << aID); return; } auto founder = _mapAccepterOptions.find(aID); if (founder == _mapAccepterOptions.end()) { LCE("Unknown AccepterID aID=" << aID); return; } if (ec) { LCE("doAccept Result Error. ec=" << ec << ", extend=" << founder->second); auto &&handler = std::bind(&SessionManager::onAcceptNewClient, this, std::placeholders::_1, std::placeholders::_2, accepter, aID); auto timer = [accepter, handler]() { accepter->doAccept(std::make_shared<TcpSocket>(), std::move(handler)); }; createTimer(5000, std::move(timer)); return; } std::string remoteIP; unsigned short remotePort = 0; s->getPeerInfo(remoteIP, remotePort); //! check white list //! --------------------- if (!founder->second._whitelistIP.empty()) { bool checkSucess = false; for (auto white : founder->second._whitelistIP) { if (remoteIP.size() >= white.size()) { if (remoteIP.compare(0,white.size(), white) == 0) { checkSucess = true; break; } } } if (!checkSucess) { LCW("Accept New Client Check Whitelist Failed remoteAdress=" << remoteIP << ":" << remotePort << ", extend=" << founder->second); accepter->doAccept(std::make_shared<TcpSocket>(), std::bind(&SessionManager::onAcceptNewClient, this, std::placeholders::_1, std::placeholders::_2, accepter, aID)); return; } else { LCI("Accept New Client Check Whitelist Success remoteAdress=" << remoteIP << ":" << remotePort << ", extend=" << founder->second); } } //! check Max Sessions if (founder->second._currentLinked >= founder->second._maxSessions) { LCW("Accept New Client. Too Many Sessions And The new socket will closed. extend=" << founder->second ); } else { LCD("Accept New Client. Accept new Sessions. The new socket remoteAddress=" << remoteIP << ":" << remotePort << ", Aready linked sessions = " << founder->second._currentLinked << ", extend=" << founder->second); founder->second._currentLinked++; founder->second._totalAcceptCount++; _lastSessionID = nextSessionID(_lastSessionID); s->initialize(_summer); TcpSessionPtr session = std::make_shared<TcpSession>(); session->getOptions() = founder->second._sessionOptions; session->setEventLoop(_summer); if (session->attatch(s, aID, _lastSessionID)) { _mapTcpSessionPtr[_lastSessionID] = session; } } //! accept next socket. accepter->doAccept(std::make_shared<TcpSocket>(), std::bind(&SessionManager::onAcceptNewClient, this, std::placeholders::_1, std::placeholders::_2, accepter, aID)); }