Пример #1
0
/**
 비동기로 recv를 시킴
 다수의 워커스레드로부터 호출됨.
*/
void XEWinConnectionInServer::tWSARecv( void )
{
	//
	do 	{
		unsigned long readbytes; 
		// 비동기로 전송처리, 큐에 올라감. 이걸해야 스레드에서 데이타가 받아짐.
	#ifdef _USING_WSA 
		WSABUF b[1]; 
		unsigned long flags = 0; 
 		memset( &m_opRecv, 0, sizeof(m_opRecv) );
		m_opRecv.typeEvent = 2;
		b[0].buf = (CHAR *)m_Buffer; 
		b[0].len = sizeof(m_Buffer); 
		if( WSARecv( m_Socket, b, 1, &readbytes, &flags, &m_opRecv, NULL ) == SOCKET_ERROR )
	#else
		// 최초 accept시에는 아래처림 == FALSE로 검사하면 안됨. 원래 0나옴
		if( ReadFile( (HANDLE)m_Socket, m_Buffer, sizeof(m_Buffer), &readbytes, &m_op ) == FALSE )
	#endif
		{
			const auto lastErr = GetLastError();
			XBREAKF( lastErr != WSAECONNRESET	&& lastErr != ERROR_IO_PENDING
						, "WSARecv error:err=%d", lastErr );
			if( lastErr != WSAECONNRESET		// 접속끊김
				&& lastErr != ERROR_IO_PENDING ) {	// IO처리중
				CONSOLE( "WSARecv error: socket=%x, error=%d", m_Socket, lastErr );
				ClearConnection();
			}
		}
	} while(0);
	//
	return;
}
Пример #2
0
void XEWinConnectionInServer::SendData( const BYTE *pBuffer, int len )
{
// 	XLOCK_OBJ;
	if( IsDisconnected() )
		return;
	if( m_Socket ) {	// 커넥션이 끊어진 이후에 올수도 있다.
 		memset( &m_opSend, 0, sizeof( m_opSend ) );
		m_opSend.typeEvent = 1;
		DWORD sendBytes = 0;
		WSABUF b[ 1 ];
		b[0].buf = (CHAR*)pBuffer;
		b[0].len = len;
		// WSARecv와 마찬가지로 미리 실행시키고 완료되면 워커스레드의 IOCP에서 통보받는다.
		auto result = WSASend( m_Socket, b, 1, &sendBytes, 0, (LPWSAOVERLAPPED)&m_opSend, nullptr );
		if( result == SOCKET_ERROR ) {
			const auto lastErr = GetLastError();
			if( XBREAK(lastErr != WSAECONNRESET 
							&& lastErr != ERROR_IO_PENDING)) {
				int numError = WSAGetLastError();
				CONSOLE_THIS( "connect", "WSAGetLastError() == 0x%x socket=%d this=0x%0x idConnect=0x%0x",
					numError, (DWORD)m_Socket, ( DWORD )this, m_idConnect );
				ClearConnection();
			} else {
				XBREAK( sendBytes != 0 && (DWORD)len != sendBytes );	// 어떤경우에 생기는지 확인하려고
			}
		} else {
			XBREAK( sendBytes != 0 && (DWORD)len != sendBytes );	// 어떤경우에 생기는지 확인하려고
		}
		// 전부다 못보낸 경우도 처리해야 할듯.
#pragma message( "check this" )
	} // Socket
}
bool FFInterface::Connect (void)
{
	b_UseLocalHeuristicEvaluator = (1 == (int)(config)"use_local_heuristic_evaluator");
	if (true == b_UseLocalHeuristicEvaluator)
	{
		if (false == InitHeuristicEvaluator ())
			return false;

		b_Active = true;
		p_FFInterface = this;
		pthread_create (&thr_SocketLoop, NULL, RunThread, this);
		pthread_detach (thr_SocketLoop);
		return true;
	}

	String sServer = (config)"cache_host";
	String sPort = (config)"cache_service";

	if (false == ClientSocket::ConnectBlocking (sServer, sPort))
	{
		cout << "   [EE] Failed to connect to cache server at "
			 << sServer << ':' << sPort << endl;
		return false;
	}

	b_KnownWorldOnly = (1 == (int)(config)"known_world_only");
	if (true == b_KnownWorldOnly)
	{
		cout << "Activating known-world-only mode." << endl;
		SendMessage (String (":[known world only]"));

		SetStandalone (true);

		Buffer bufTemp;
		size_t iMessageSize = 0;
		while (true)
		{
			char zData [RECEIVE_BUFFER + 1];
			long lBytes = ReceiveBlocking (zData, RECEIVE_BUFFER, 100);
			if (lBytes > 0)
				bufTemp.Append (zData, lBytes);

			if (false == bufTemp.ReadFromIndex (0, &iMessageSize, sizeof (size_t)))
				continue;
			if (iMessageSize > bufTemp.Length ())
				continue;
			break;
		}

		Buffer bufResponse = bufTemp.PopFirstMessageAsBuffer (iMessageSize);
		bufResponse.DropFront (sizeof (size_t));
		String sMessage = bufResponse;
		if (":Known-world-only mode active" == sMessage)
			cout << "   Known world only mode active." << endl;
		else
		{
			cout << "   [WARNING] Failed to activate known-world-only mode.\n"
					"   Got following response from cache: ["
				 << sMessage << ']' << endl;
		}
		SetStandalone (false);
	}

	ClearConnection ();

	b_Active = true;
	pthread_create (&thr_SocketLoop, NULL, RunThread, this);
	pthread_detach (thr_SocketLoop);

	return true;
}