bool ListenerWorker::onUpdateTimer(void* args) { UInt32 currTime = TimeUtil::getTimeSec(); if (currTime - mLastSecurityCheckTime >= 300000) { mLastSecurityCheckTime = currTime; for (Set<TcpConnection*>::Iter* iter = mMainConnectionSet.begin(); iter != NULL;) { TcpConnection* conn = iter->mValue; if (conn) { if (currTime - conn->getRecvTimeStamp() >= CLIENT_CONNECTION_SECURITY_CHECK_INTERVAL) { LOG_WARN("Connection [%s:%u] was closed for timeout.", conn->getFromIp().c_str(), conn->getFromPort()); LYNX_DEREGISTER_RECEIVED(conn, this, &ListenerWorker::onMainReceived); LYNX_DEREGISTER_CONNECT_BROKEN(conn, this, &ListenerWorker::onMainDisconnected); conn->close(); iter = mMainConnectionSet.erase(iter); XDELETE(conn); } else { iter = mMainConnectionSet.next(iter); } } } for (Set<TcpConnection*>::Iter* iter = mGMConnectionSet.begin(); iter != NULL;) { TcpConnection* conn = iter->mValue; if (conn) { if (currTime - conn->getRecvTimeStamp() >= CLIENT_CONNECTION_SECURITY_CHECK_INTERVAL) { LOG_WARN("Connection [%s:%u] was closed for timeout.", conn->getFromIp().c_str(), conn->getFromPort()); LYNX_DEREGISTER_RECEIVED(conn, this, &ListenerWorker::onGMReceived); LYNX_DEREGISTER_CONNECT_BROKEN(conn, this, &ListenerWorker::onGMDisconnected); conn->close(); iter = mGMConnectionSet.erase(iter); XDELETE(conn); } else { iter = mGMConnectionSet.next(iter); } } } } return true; }
err_t TcpConnection::staticOnReceive(void *arg, tcp_pcb *tcp, pbuf *p, err_t err) { // debugf("Static OnReceive buf = %d", tcp_sndbuf(tcp)); TcpConnection* con = (TcpConnection*)arg; err_t ret_err; //Serial.println("echo_recv!"); if (con == NULL) { if (p != NULL) { /* Inform TCP that we have taken the data. */ tcp_recved(tcp, p->tot_len); pbuf_free(p); } closeTcpConnection(tcp); return ERR_OK; } else con->sleep = 0; if (err != ERR_OK /*&& err != ERR_CLSD && err != ERR_RST*/) { debugf("Received ERROR %d", err); /* exit and free resources, for unkown reason */ if (p != NULL) { /* Inform TCP that we have taken the data. */ tcp_recved(tcp, p->tot_len); pbuf_free(p); } closeTcpConnection(tcp); // ?? con->tcp = NULL; con->onError(err); //con->close(); return err == ERR_ABRT ? ERR_ABRT : ERR_OK; } //if (tcp != NULL && tcp->state == ESTABLISHED) // If active /* We have taken the data. */ if (p != NULL) tcp_recved(tcp, p->tot_len); err_t res = con->onReceive(p); if (p != NULL) pbuf_free(p); else { con->close(); closeTcpConnection(tcp); } con->checkSelfFree(); //debugf("<staticOnReceive"); return res; }
//主动关闭连接 void NetWork::close(int handle) { TRACE(__PRETTY_FUNCTION__); TcpConnection *conn = _online_user.getconn(handle); if (conn != NULL) { //从kqueue/epoll中线拿出来,防止再触发事件,导致各种复杂耦合 _sock_event->remove_event(conn); //判断removeconn的返回值,主线程和业务线程同时调用close时,产生conn->close重复调用 if (_online_user.removeconn(handle)) { conn->close(); } conn->release(); } return; }
int Network::Server::initConnection(const char* host, const char* port) { if (strlen(host) > INET6_ADDRSTRLEN || strlen(port) > MAX_PORT_LENGTH ) { DEBUGPRINT("SERVER ERROR:\t Invalid port or host length to init\n"); return -2; } if (host == NULL || port == NULL) { DEBUGPRINT("SERVER ERROR:\t Invalid arguments to init\n"); } LOGPRINT("SERVER STATUS:\t Connection to host:%s:%s\n", host, port); addrinfo l_hints, *l_result, *l_p; int l_resvalue = -1; memset(&l_hints, 0, sizeof(struct addrinfo) ); l_hints.ai_family = AF_UNSPEC; l_hints.ai_socktype = SOCK_STREAM; if ((l_resvalue = getaddrinfo(host, port, &l_hints, &l_result)) == -1) { DEBUGPRINT("SERVER ERROR:\t Could not get addrinfo: %s\n", gai_strerror(l_resvalue)); return -1; } TcpConnection * conn = new TcpConnection(); if (conn == NULL) { DEBUGPRINT("SERVER ERROR:\t Could not create new TCP Connection\n"); return -1; } for (l_p = l_result; l_p != NULL; l_p = l_p->ai_next) { if ((l_resvalue =conn->socket(l_p)) != 0) { if (l_resvalue == -1) { DEBUGPRINT("SERVER ERROR:\t Could not connect socket trying next\n"); } else if (l_resvalue == -2) { DEBUGPRINT("SERVER ERROR:\t Argument error to socket\n"); } else { DEBUGPRINT("SERVER ERROR:\t Invalid Return\n"); } continue; } if ((l_resvalue = conn->connect(l_p)) != 0) { if (l_resvalue == -1) { DEBUGPRINT("SERVER ERROR:\t Could not connect to server/port\n"); } else if (l_resvalue == -2) { DEBUGPRINT("SERVER ERROR:\t Argument error to connect\n"); } else { DEBUGPRINT("SERVER ERROR:\t Invalid return\n"); } conn->close(); continue; } break; } if (l_p == NULL) { DEBUGPRINT("SERVER FAILURE:\t Failed to connect to %s:%s\n", host, port); return -1; } int fileDesc = conn->getSocketFd(); int enable = 1; if (setsockopt(fileDesc, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) == -1) { return -1; } if ( setnonblock(fileDesc) == -1) { DEBUGPRINT("SERVER ERROR:\t Could not set socket to non-blocking\n"); } if( addHandler(fileDesc, EPOLLET|EPOLLIN|EPOLLHUP, conn ) == -1) { DEBUGPRINT("SERVER ERROR:\t Could not add handler to tcpConnection\n"); return -1; } return fileDesc; }