void Session::Worker() { sLog->StaticOut("Network worker thread running"); sApp->ThreadStatus.sessionworker = true; char* buf = new char[BUFFER_LEN]; int result, error; Player* pClient = NULL; std::list<Player*>::iterator itr; while(1) { if (clientList.empty()) { // Wait for longer period, no need to check for socket traffic so often if nobody's connected boost::this_thread::sleep(boost::posix_time::milliseconds(100)); continue; } for (itr = clientList.begin(); itr != clientList.end();) { pClient = (*itr); // Who wants ugly star in brackets?! if (pClient) { memset(buf,0,BUFFER_LEN); result = recv(pClient->m_socket, buf, BUFFER_LEN, 0); error = LASTERROR(); if (result > 0) { sLog->NetworkOut(pClient,"Received data, size: %u",result); ProcessPacket(BuildPacket(buf,result), pClient); } else if (result == 0 || error == SOCKETCONNRESET) { sLog->NetworkOut(pClient,"Client disconnected"); sInstanceManager->RemovePlayerFromInstances(pClient); itr = clientList.erase(itr); continue; } else { if (error != SOCKETWOULDBLOCK && error != 0) { //error sLog->NetworkOut(pClient,"Unhandled socket error: %u",error); } } } ++itr; } // Some waiting time, could be changed if needed, but thread have to wait since select() is not present boost::this_thread::sleep(boost::posix_time::milliseconds(10)); } }
void Session::Acceptor() { sLog->StaticOut("Network acceptor thread running"); sApp->ThreadStatus.sessionacceptor = true; int res, error; Player* pNew = new Player; pNew->m_addrLen = sizeof(pNew->m_sockInfo); SOCK result; res = listen(m_socket, 10); if (res == -1) { sLog->ErrorOut("Couldn't create connection queue"); sApp->ThreadStatus.sessionacceptor = false; return; } while(1) { result = accept(m_socket, (sockaddr*)&pNew->m_sockInfo, &pNew->m_addrLen); error = LASTERROR(); if (result == INVALID_SOCKET && error == SOCKETWOULDBLOCK) { //failed to accept //TODO: some error message } else if (result == INVALID_SOCKET && error != SOCKETWOULDBLOCK) { //invalid socket //TODO: some error message } else { pNew->m_socket = result; pNew->m_addrLen = sizeof(pNew->m_sockInfo); sLog->StringOut("Accepting connection from %s",inet_ntoa((in_addr)pNew->m_sockInfo.sin_addr)); clientList.push_back(pNew); sLog->NetworkOut(pNew,"Inserted into client list"); pNew = new Player; pNew->m_addrLen = sizeof(pNew->m_sockInfo); } // Wait for some time, could be changed if needed boost::this_thread::sleep(boost::posix_time::milliseconds(10)); } }
void Session::Worker() { sLog->StaticOut("Network worker thread running"); sApp->ThreadStatus.sessionworker = true; char* buf = new char[BUFFER_LEN]; int result, error; SOCK res; Player* pClient = NULL; Player* pNew = new Player; pNew->m_addrLen = sizeof(pNew->m_sockInfo); std::list<Player*>::iterator itr; while(1) { res = accept(m_socket, (sockaddr*)&pNew->m_sockInfo, &pNew->m_addrLen); error = LASTERROR(); if (res == INVALID_SOCKET && error == SOCKETWOULDBLOCK) { // zadne prichozi spojeni } else if (res == INVALID_SOCKET && error != SOCKETWOULDBLOCK) { sLog->ErrorOut("Socket error: %i", error); } else { pNew->m_socket = res; pNew->m_addrLen = sizeof(pNew->m_sockInfo); sLog->DebugOut("Accepting connection from %s",inet_ntoa((in_addr)pNew->m_sockInfo.sin_addr)); clientList.push_back(pNew); sLog->NetworkDebugOut(pNew,"Inserted into client list"); pNew = new Player; pNew->m_addrLen = sizeof(pNew->m_sockInfo); } if (clientList.empty()) { // Wait for longer period, no need to check for socket traffic so often if nobody's connected boost::this_thread::sleep(boost::posix_time::milliseconds(100)); continue; } for (itr = clientList.begin(); itr != clientList.end();) { pClient = (*itr); // Who wants ugly star in brackets?! if (pClient) { memset(buf,0,BUFFER_LEN); result = recv(pClient->m_socket, buf, BUFFER_LEN, 0); error = LASTERROR(); if (result > 0) { sLog->NetworkDebugOut(pClient,"Received data, size: %u",result); SmartPacket* parsed = BuildPacket(buf,result); if (parsed) { sLog->NetworkDebugOut(pClient,"Opcode 0x%.2X, size %u", parsed->GetOpcode(), parsed->GetSize()); ProcessPacket(parsed, pClient); int32 totalparsed = parsed->GetSize()+8; while (totalparsed < result) { parsed = BuildPacket(buf+totalparsed, result-totalparsed); if (parsed) { sLog->NetworkDebugOut(pClient,"Parsed additional %u bytes",parsed->GetSize()); sLog->NetworkDebugOut(pClient,"Opcode 0x%.2X, size %u", parsed->GetOpcode(), parsed->GetSize()); ProcessPacket(parsed, pClient); totalparsed += parsed->GetSize()+8; } else break; } } } else if (result == 0 || error == SOCKETCONNRESET) { sLog->NetworkDebugOut(pClient,"Client disconnected"); sInstanceManager->RemovePlayerFromInstances(pClient); itr = clientList.erase(itr); continue; } else { if (error != SOCKETWOULDBLOCK && error != 0) { //error sLog->NetworkOut(pClient,"Unhandled socket error: %u",error); } } } ++itr; } // Some waiting time, could be changed if needed, but thread have to wait since select() is not present // technically, this counts as "yield" on Windows boost::this_thread::sleep(boost::posix_time::milliseconds(1)); } }