Esempio n. 1
0
void tcp_frame::run()
{
	if (_Imp->bOpen)
		return;

	if (_Imp->errorCode)
	{
		NET_LOG.console("tcp_frame start failed:{0}", _Imp->errorCode.message().c_str());
		return;
	}

	NET_LOG.console("tcp_frame start succeed");

	_Imp->servicepool.run();

	if (_Imp->bCheckTimeOut)
	{
		NET_LOG.console("tcp_frame start check timeout thread succeed");
		_Imp->timeOutThread.set_interval(_Imp->timeoutCheckInterval);
		_Imp->timeOutThread.onUpdate = std::bind(&tcp_frame::checkTimeOut, this, std::placeholders::_1);
		_Imp->timeOutThread.run();
	}

	postAccept();

	_Imp->bOpen = true;
}
Esempio n. 2
0
void TCPServer::handleAccept(
	PSocketContext pSocketContext, 
	PIOContext pIOContext)
{
	setsockopt(pIOContext->fd, SOL_SOCKET, 
		SO_UPDATE_ACCEPT_CONTEXT, 
		(char*)&pSocketContext->fd, sizeof(SOCKET));

	sockaddr_in* clientAddr = nullptr;
	sockaddr_in* localAddr = nullptr;

	int clientLen = sizeof(sockaddr_in);
	int localLen = clientLen;  

	_fnGetAcceptExSockAddrs(
		pIOContext->overlappedBuffer.buf, 0, 
		sizeof(sockaddr_in) + 16, sizeof(sockaddr_in) + 16,
		(sockaddr**)&localAddr, &localLen, 
		(sockaddr**)&clientAddr, &clientLen);

	auto clientPort = ntohs(clientAddr->sin_port);
	auto wClientIP = AnsiToUnicode(inet_ntoa(clientAddr->sin_addr));
	LOG("创建新会话[%s-%d]", wClientIP.c_str(), clientPort);

	PSocketContext pClientSocketContext = new SocketContext();
	pClientSocketContext->fd = pIOContext->fd;
	pClientSocketContext->clientIP = wClientIP;
	pClientSocketContext->clientPort = clientPort;

	if(!bind2IOCP(pClientSocketContext)){
		delete pClientSocketContext;
		pClientSocketContext = nullptr;
		return;
	}

	// 立即投递接受数据请求
	auto client = new TCPServerSession(this, pClientSocketContext);
	client->postRecv(nullptr);
	addClients(client);

	// 立即投递下一个accept请求
	pIOContext->resetBuffer();
	postAccept(pIOContext);
}
Esempio n. 3
0
void tcp_frame::postAccept()
{
	if (!_Imp->acceptor.is_open())
	{
		return;
	}

	auto& ser = _Imp->servicepool.get_service();
	auto sock = std::make_shared<socket>(_hander,ser);
	sock->setmodule_id(_Imp->moduleid);

	_Imp->acceptor.async_accept(sock->get_socket(), [sock, this, &ser](const asio::error_code& e) {
		if (!e)
		{
			ser.add_socket(sock);
			postAccept();
			return;
		}
		_Imp->errorCode = e;
	});
}
Esempio n. 4
0
bool TCPServer::createListenerSocket(unsigned short port)
{
	_listenSocketContext = new SocketContext();

	_listenSocketContext->fd = WSASocket(AF_INET, 
		SOCK_STREAM, 0, 0, 0, WSA_FLAG_OVERLAPPED);
	if(INVALID_SOCKET == _listenSocketContext->fd) {
		SYSLOG("初始化Socket失败", WSAGetLastError());
		return false;
	}

	if(!bind2IOCP(_listenSocketContext)) {
		return false;
	}

	sockaddr_in netAddr;  
	memset(&netAddr, 0, sizeof(sockaddr_in));
	netAddr.sin_family = AF_INET;  
	netAddr.sin_port = htons(port);
	netAddr.sin_addr.s_addr = htonl(INADDR_ANY);

	if(SOCKET_ERROR == bind(_listenSocketContext->fd, 
		(sockaddr*)&netAddr, sizeof(netAddr))) {
		SYSLOG("bind()执行错误", WSAGetLastError());
		return false;
	}

	if(SOCKET_ERROR == listen(_listenSocketContext->fd, 128)) {
		SYSLOG("listen()执行出现错误", WSAGetLastError());
		return false;
	}

	GUID guidAcceptEx = WSAID_ACCEPTEX;  
	GUID guidAcceptExSockAddrs = WSAID_GETACCEPTEXSOCKADDRS; 
	unsigned long dwBytes = 0;

	if(SOCKET_ERROR == WSAIoctl(
		_listenSocketContext->fd, SIO_GET_EXTENSION_FUNCTION_POINTER, 
		&guidAcceptEx, sizeof(guidAcceptEx), 
		&_fnAcceptEx, sizeof(_fnAcceptEx), 
		&dwBytes, nullptr, nullptr)) {  
		SYSLOG("获取AcceptEx函数指针失败", WSAGetLastError()); 
		return false;  
	}  

	if(SOCKET_ERROR == WSAIoctl(
		_listenSocketContext->fd, SIO_GET_EXTENSION_FUNCTION_POINTER, 
		&guidAcceptExSockAddrs, sizeof(guidAcceptExSockAddrs), 
		&_fnGetAcceptExSockAddrs, sizeof(_fnGetAcceptExSockAddrs),   
		&dwBytes, nullptr, nullptr)) {  
		SYSLOG("获取GetAcceptExSockAddrs函数指针失败", WSAGetLastError());  
		return false; 
	}  

	for(int i = 0; i < s_maxPostAccept; i++) {
		auto pIOContext = _listenSocketContext->getNewIOContext();
		if(!postAccept(pIOContext)) {
			_listenSocketContext->removeIOContext(pIOContext);
		}
	}

	unsigned id = 0;
	_pThreads = new HANDLE[_threads];
	for(int i = 0; i < _threads; i++) {
		_pThreads[i] = (HANDLE)_beginthreadex(nullptr, 0, 
			&workerLoop, (void*)this, 0, &id);
	}

	LOG("IOCP初始化成功,建立[%d]个消息处理工作者", _threads);
	return true;
}