/** 비동기로 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; }
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; }