Пример #1
0
bool TCPServer::handleIO(
	PSocketContext pSocketContext,
	PIOContext pIOContext,
	BOOL status) 
{
	if(!status) {  
		if(!handleError(pSocketContext)) {
			return false;
		}

		return true;
	}

	if( (0 == pIOContext->overlapped.InternalHigh) && 
		(pIOContext->opType & (OPT_READ + OPT_WRITE))) {  
		handleClose(pSocketContext);
		return true;
	}

	switch(pIOContext->opType) {
		case OPT_ACCEPT: handleAccept(pSocketContext, pIOContext); break;
		case OPT_READ: handleRead(pSocketContext, pIOContext); break;
		case OPT_WRITE: handleWrite(pSocketContext, pIOContext); break;
		default: LOG("操作类型参数异常"); break;
	}

	return true;
}
Пример #2
0
void Server::checkAndDispatchEpoll(int epollMillis) {
    constexpr int maxEvents = 256;
    epoll_event events[maxEvents];

    std::list<Connection*> toBeDeleted;
    int numEvents = epoll_wait(_epollFd, events, maxEvents, epollMillis);
    if (numEvents == -1) {
        if (errno != EINTR) {
            LS_ERROR(_logger, "Error from epoll_wait: " << getLastError());
        }
        return;
    }
    if (numEvents == maxEvents) {
        static time_t lastWarnTime = 0;
        time_t now = time(nullptr);
        if (now - lastWarnTime >= 60) {
            LS_WARNING(_logger, "Full event queue; may start starving connections. "
                    "Will warn at most once a minute");
            lastWarnTime = now;
        }
    }
    for (int i = 0; i < numEvents; ++i) {
        if (events[i].data.ptr == this) {
            if (events[i].events & ~EPOLLIN) {
                LS_SEVERE(_logger, "Got unexpected event on listening socket ("
                        << EventBits(events[i].events) << ") - terminating");
                _terminate = true;
                break;
            }
            handleAccept();
        } else if (events[i].data.ptr == &_eventFd) {
            if (events[i].events & ~EPOLLIN) {
                LS_SEVERE(_logger, "Got unexpected event on management pipe ("
                        << EventBits(events[i].events) << ") - terminating");
                _terminate = true;
                break;
            }
            handlePipe();
        } else {
            auto connection = reinterpret_cast<Connection*>(events[i].data.ptr);
            if (handleConnectionEvents(connection, events[i].events) == Close) {
                toBeDeleted.push_back(connection);
            }
        }
    }
    // The connections are all deleted at the end so we've processed any other subject's
    // closes etc before we call onDisconnect().
    for (auto it = toBeDeleted.begin(); it != toBeDeleted.end(); ++it) {
        auto connection = *it;
        if (_connections.find(connection) == _connections.end()) {
            LS_SEVERE(_logger, "Attempt to delete connection we didn't know about: " << (void*)connection
                    << formatAddress(connection->getRemoteAddress()));
            _terminate = true;
            break;
        }
        LS_DEBUG(_logger, "Deleting connection: " << formatAddress(connection->getRemoteAddress()));
        delete connection;
    }
}
Пример #3
0
	/**
	 * The server will listen on localhost/ip-address on the port
	 */
	Server(boost::asio::io_service& an_io_service, short port, Robot* aRobot)
	    : io_service(an_io_service)
	    , acceptor(io_service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port))
	    , robot(aRobot)
	{
		// start handling incomming connections
		handleAccept(NULL, boost::system::error_code());
	}
void TcpProxyClientAcceptor::registerForAccept() {
	auto pSession = TcpProxySession::create(m_ioServicePool.getIoService());
	auto sharedThis = shared_from_this();
	m_acceptor.async_accept(pSession->getClientSocket(),
			[=] (const boost::system::error_code& error)
			{
				sharedThis->handleAccept(pSession, error);
			});
}
Пример #5
0
int TCPServer::epoll()
{
	//1.epoll_wait
	int nfds = epoll_wait(m_nEpollFd, m_events, m_fdCount, 5000);
	if(nfds == -1)
	{
		ERROR("TCPServer", "epoll wait error:%s epool_fd:%d fd_count:%d", strerror(GET_LAST_ERROR), m_nEpollFd, m_fdCount);
		return VIOLET_ERROR_SOCKET_EPOLL_WAIT_FAILED;
	}
	else if(nfds == 0)
	{
		VDEBUG("TCPServer", "epoll wait timeout.");
		return VIOLET_ERROR_SOCKET_EPOLL_TIMEOUT;
	}

	//2.处理注册事件
	for(int i = 0; i < nfds; i++)
	{
		//2.1 监听事件发生意味新的连接到来
		if(m_events[i].data.fd == m_objListenTCPTransfer->getSocket()) 
		{
			INFO("TCPServer", "server handle.");
			int nRet = handleAccept();
			if(nRet != 0) 
			{
				ERROR("TCPServer", "tcp new connection failure.");
				continue;
			}
		}
		else
		{
			//2.2 客户端连接产生事件
			int nRet = handleEvent((TCPLinkReceiver *)m_events[i].data.ptr, &m_events[i]);
			if (VIOLET_ERROR_SOCKET_SEND_FAILED == nRet || VIOLET_ERROR_SOCKET_RECV_FAILED == nRet)
			{
				closeConnection((TCPLinkReceiver *)m_events[i].data.ptr);
			}
		}
	}

	return VIOLET_SUCCESS;
}
Пример #6
0
void Server::start() {
	connectToUnifier("localhost", 30000);
	registerService("FE");

	int fd = 0;
	unsigned long ticks = 0;

	LOG_INFO(logger, "Starting the server");
	while (true) {
		waitForTick();
		while((fd = accept(m_sock, NULL, NULL)) > 0) {
			handleAccept(fd);
		}

		m_sessionManager.tick();

		sendTock();
		ticks++;
	}
}
void selectPass(void) {
	int i;
	fd_set readfds, writefds;
	FD_ZERO(&readfds);
	FD_ZERO(&writefds);
	/* Server sockets */
	for (i = 0; (i < seTotal); i++) {
		if (seFds[i] != INVALID_SOCKET) {
			FD_SET(seFds[i], &readfds);
		}
	}
	/* Connection sockets */
	for (i = 0; (i < coTotal); i++) {
		if (coClosed[i]) {
			continue;
		}
		if (coClosing[i]) {
			if (!reClosed[i]) {
				FD_SET(reFds[i], &writefds);
			}	
			if (!loClosed[i]) {
				FD_SET(loFds[i], &writefds);
			}	
		}
		/* Get more input if we have room for it */
		if ((!reClosed[i]) && (coInputRPos[i] < bufferSpace)) {
			FD_SET(reFds[i], &readfds);
		}
		/* Send more output if we have any */	
		if ((!reClosed[i]) && (coOutputWPos[i] < coOutputRPos[i])) {
			FD_SET(reFds[i], &writefds);
		}	
		/* Accept more output from the local 
			server if there's room */
		if ((!loClosed[i]) && (coOutputRPos[i] < bufferSpace)) {
			FD_SET(loFds[i], &readfds);
		}
		/* Send more input to the local server 
			if we have any */
		if ((!loClosed[i]) && (coInputWPos[i] < coInputRPos[i])) {
			FD_SET(loFds[i], &writefds);
		}	
	}
	select(maxfd + 1, &readfds, &writefds, 0, 0);
	for (i = 0; (i < seTotal); i++) {
		if (seFds[i] != -1) {
			if (FD_ISSET(seFds[i], &readfds)) {
				handleAccept(i);
			}
		}
	}
	for (i = 0; (i < coTotal); i++) {
		if (coClosed[i]) {
			continue;
		}
		if (!reClosed[i]) {
			if (FD_ISSET(reFds[i], &readfds)) {
				handleRemoteRead(i);
			}
		}
		if (!reClosed[i]) {
			if (FD_ISSET(reFds[i], &writefds)) {
				handleRemoteWrite(i);
			}
		}
		if (!loClosed[i]) {
			if (FD_ISSET(loFds[i], &readfds)) {
				handleLocalRead(i);
			}
		}
		if (!loClosed[i]) {
			if (FD_ISSET(loFds[i], &writefds)) {
				handleLocalWrite(i);
			}
		}
		if (loClosed[i] && reClosed[i]) {
			coClosed[i] = 1;
		}	
	}
}
Пример #8
0
	void Server::startAccept ()
	{
		m_conn.reset (new ClientConnection (m_io, m_dbMgr));
		m_acceptor.async_accept (m_conn->getSocket (),
				[this] (const boost::system::error_code& ec) { handleAccept (ec); });
	}
Пример #9
0
static void selectPass(void) {

	int const fdSetCount = maxfd / FD_SETSIZE + 1;
#	define FD_ZERO_EXT(ar) for (int i = 0; i < fdSetCount; ++i) { FD_ZERO(&(ar)[i]); }
#	define FD_SET_EXT(fd, ar) FD_SET((fd) % FD_SETSIZE, &(ar)[(fd) / FD_SETSIZE])
#	define FD_ISSET_EXT(fd, ar) FD_ISSET((fd) % FD_SETSIZE, &(ar)[(fd) / FD_SETSIZE])

	fd_set readfds[fdSetCount], writefds[fdSetCount];
	FD_ZERO_EXT(readfds);
	FD_ZERO_EXT(writefds);
	/* Server sockets */
	for (int i = 0; i < seTotal; ++i) {
		if (seInfo[i].fd != INVALID_SOCKET) {
			FD_SET_EXT(seInfo[i].fd, readfds);
		}
	}
	/* Connection sockets */
	for (int i = 0; i < coTotal; ++i) {
		ConnectionInfo *cnx = &coInfo[i];
		if (cnx->local.fd != INVALID_SOCKET) {
			/* Accept more output from the local
				server if there's room */
			if (cnx->local.recvPos < RINETD_BUFFER_SIZE) {
				FD_SET_EXT(cnx->local.fd, readfds);
			}
			/* Send more input to the local server
				if we have any, or if we’re closing */
			if (cnx->local.sentPos < cnx->remote.recvPos || cnx->coClosing) {
				FD_SET_EXT(cnx->local.fd, writefds);
			}
		}
		if (cnx->remote.fd != INVALID_SOCKET) {
			/* Get more input if we have room for it */
			if (cnx->remote.recvPos < RINETD_BUFFER_SIZE) {
				FD_SET_EXT(cnx->remote.fd, readfds);
			}
			/* Send more output if we have any, or if we’re closing */
			if (cnx->remote.sentPos < cnx->local.recvPos || cnx->coClosing) {
				FD_SET_EXT(cnx->remote.fd, writefds);
			}
		}
	}
	select(maxfd + 1, readfds, writefds, 0, 0);
	for (int i = 0; i < coTotal; ++i) {
		ConnectionInfo *cnx = &coInfo[i];
		if (cnx->remote.fd != INVALID_SOCKET) {
			if (FD_ISSET_EXT(cnx->remote.fd, readfds)) {
				handleRead(cnx, &cnx->remote, &cnx->local);
			}
		}
		if (cnx->remote.fd != INVALID_SOCKET) {
			if (FD_ISSET_EXT(cnx->remote.fd, writefds)) {
				handleWrite(cnx, &cnx->remote, &cnx->local);
			}
		}
		if (cnx->local.fd != INVALID_SOCKET) {
			if (FD_ISSET_EXT(cnx->local.fd, readfds)) {
				handleRead(cnx, &cnx->local, &cnx->remote);
			}
		}
		if (cnx->local.fd != INVALID_SOCKET) {
			if (FD_ISSET_EXT(cnx->local.fd, writefds)) {
				handleWrite(cnx, &cnx->local, &cnx->remote);
			}
		}
	}
	/* Handle servers last because handleAccept() may modify coTotal */
	for (int i = 0; i < seTotal; ++i) {
		ServerInfo *srv = &seInfo[i];
		if (srv->fd != INVALID_SOCKET) {
			if (FD_ISSET_EXT(srv->fd, readfds)) {
				handleAccept(srv);
			}
		}
	}
}