int UDPSocket::ReceiveFrom( void* inToReceive, int inMaxLength, SocketAddress& outFromAddress ) { socklen_t fromLength = outFromAddress.GetSize(); int readByteCount = recvfrom( mSocket, static_cast< char* >( inToReceive ), inMaxLength, 0, &outFromAddress.mSockAddr, &fromLength ); if( readByteCount >= 0 ) { return readByteCount; } else { int error = SocketUtil::GetLastError(); if( error == WSAEWOULDBLOCK ) { return 0; } else if( error == WSAECONNRESET ) { //this can happen if a client closed and we haven't DC'd yet. //this is the ICMP message being sent back saying the port on that computer is closed LOG( "Connection reset from %s", outFromAddress.ToString().c_str() ); return -WSAECONNRESET; } else { SocketUtil::ReportError( "UDPSocket::ReceiveFrom" ); return -error; } } }
//---------------------------------------------------------------------------- void SocketImpl::Bind6(const SocketAddress& address, bool reuseAddress, bool ipV6Only) { #if defined(PX2_HAVE_IPV6) if (address.GetFamily() != IPAddress::IPv6) { assertion(false, "SocketAddress must be an IPv6 address"); } if (mSocket == PX2_INVALID_SOCKET) { Init(address.GetAF()); } #ifdef IPV6_V6ONLY SetOption(IPPROTO_IPV6, IPV6_V6ONLY, ipV6Only ? 1 : 0); #else if (ipV6Only) { assertion(false, "IPV6_V6ONLY not defined."); } #endif if (reuseAddress) { SetReuseAddress(true); SetReusePort(true); } int rc = ::bind(mSocket, address.GetAddr(), address.GetAddrLength()); if (rc != 0) { NetError::Error(address.ToString()); } #else assertion(false, "No IPv6 support available.\n"); #endif }
void NetworkManagerServer::HandlePacketFromNewClient( InputMemoryBitStream& inInputStream, const SocketAddress& inFromAddress ) { //read the beginning- is it a hello? uint32_t packetType; inInputStream.Read( packetType ); if( packetType == kHelloCC ) { //read the name string name; inInputStream.Read( name ); ClientProxyPtr newClientProxy = std::make_shared< ClientProxy >( inFromAddress, name, mNewPlayerId++ ); mAddressToClientMap[ inFromAddress ] = newClientProxy; mPlayerIdToClientMap[ newClientProxy->GetPlayerId() ] = newClientProxy; //tell the server about this client, spawn a cat, etc... //if we had a generic message system, this would be a good use for it... //instead we'll just tell the server directly static_cast< Server* > ( Engine::sInstance.get() )->HandleNewClient( newClientProxy ); //and welcome the client... SendWelcomePacket( newClientProxy ); //and now init the replication manager with everything we know about! for( const auto& pair: mNetworkIdToGameObjectMap ) { newClientProxy->GetReplicationManagerServer().ReplicateCreate( pair.first, pair.second->GetAllStateMask() ); } } else { //bad incoming packet from unknown client- we're under attack!! LOG( "Bad incoming packet from unknown client at socket %s", inFromAddress.ToString().c_str() ); } }
//---------------------------------------------------------------------------- int SocketImpl::ConnectB(const SocketAddress& address, const Timespan& timeout) { if (mSocket == PX2_INVALID_SOCKET) { Init(address.GetAF()); } SetBlocking(false); int rc = ::connect(mSocket, address.GetAddr(), address.GetAddrLength()); if (rc != 0) { int err = NetError::LastError(); if (err != PX2_EINPROGRESS && err != PX2_EWOULDBLOCK) { NetError::Error(err, address.ToString()); } if (!Poll(timeout, SELECT_READ | SELECT_WRITE | SELECT_ERROR)) { assertion(false, "connect timed out:%s", address.ToString()); } err = GetSocketError(); if (err != 0) { NetError::Error(err); } } SetBlocking(true); return rc; }
//---------------------------------------------------------------------------- void SocketImpl::Bind(const SocketAddress& address, bool reuseAddress) { if (mSocket == PX2_INVALID_SOCKET) { Init(address.GetAF()); } if (reuseAddress) { SetReuseAddress(true); SetReusePort(true); } int rc = ::bind(mSocket, address.GetAddr(), address.GetAddrLength()); if (rc != 0) { NetError::Error(address.ToString()); } }
//---------------------------------------------------------------------------- int SocketImpl::ConnectNB(const SocketAddress& address) { if (mSocket == PX2_INVALID_SOCKET) { Init(address.GetAF()); } SetBlocking(false); int rc = ::connect(mSocket, address.GetAddr(), address.GetAddrLength()); if (rc != 0) { int err = NetError::LastError(); if (err != PX2_EINPROGRESS && err != PX2_EWOULDBLOCK) { NetError::Error(err, address.ToString()); } } return rc; }
//---------------------------------------------------------------------------- int SocketImpl::ConnectB(const SocketAddress& address) { if (mSocket == PX2_INVALID_SOCKET) { Init(address.GetAF()); } int rc; do { System::SleepSeconds(0.1f); rc = ::connect(mSocket, address.GetAddr(), address.GetAddrLength()); } while (rc != 0 && NetError::LastError() == PX2_EINTR); if (rc != 0) { int err = NetError::LastError(); NetError::Error(err, address.ToString()); } return rc; }
void ShooterGame::Update(double dt) { SocketAddress socketAddress; int recv; do { char data[1500] = { 0 }; recv = mSocket->RecvFrom(data, sizeof(data), socketAddress); if (recv <= 0) continue; std::string address = socketAddress.ToString(); ProcessMessage(address, std::string(data)); } while (recv >= 0); mSendTime += dt; if (mSendTime >= 0.2f) { mSendTime = 0.0f; if (MartEngine::Args::Get()[1] == "Server") { } else { for (auto const & object : level->GetObjects()) { if(object.second->GetName().compare(0, std::string("Bullet").length(), "Bullet") == 0) { MartEngine::GameObjectPtr bullet = object.second; MartEngine::Vector3 a(bullet->GetRigidBody()->GetPosition() - MartEngine::Vector3(0.f, 0.5f, 0.f)); MartEngine::Vector3 b(mClientPlayer->GetRigidBody()->GetPosition()); MartEngine::Vector3 c(a - b); float d2 = c.GetX()*c.GetX() + c.GetY()*c.GetY() + c.GetZ()*c.GetZ(); if (d2 < 1.0f) { mClientHP--; bullet->GetRigidBody()->SetPosition(MartEngine::Vector3(0, 0, 0)); if (mClientHP == 0) { int randX = (rand() % 100) - 50; int randZ = (rand() % 100) - 50; mClientPlayer->GetRigidBody()->SetPosition(MartEngine::Vector3(randX, 5.5f, randZ)); mClientHP = 3; } mClientPlayer->GetMeshComponent()->SetTexture(MartEngine::PngManager::Get().GetPngTexture("Health" + std::to_string(mClientHP) + ".png")); } } } for (auto const & messageQueue : mMessageQueue) { if (mClientPlayer == nullptr) break; float x = mClientPlayer->GetTranslation().GetX(); float z = mClientPlayer->GetTranslation().GetZ(); float rx = mClientPlayer->GetRotation().GetVectorX(); float ry = mClientPlayer->GetRotation().GetVectorY(); float rz = mClientPlayer->GetRotation().GetVectorZ(); float rs = mClientPlayer->GetRotation().GetScalar(); char buffer[300] = { 0 }; sprintf_s(buffer, "Server_UpdatePlayerStats|%s|%f|%f|%d|%f|%f|%f|%f",mClientPlayer->GetName().c_str(),x,z,mClientHP,rx,ry,rz,rs); messageQueue.second->Add(std::string(buffer) + "|" + mClientID); } } for (auto const & messageQueue : mMessageQueue) { for (auto const & unacked : messageQueue.second->GetUnAcked()) { std::string msg = std::to_string(unacked.first) + "|" + unacked.second; SocketAddressPtr toAddr = messageQueue.first; mSocket->SendTo(msg.c_str(), msg.length(), *toAddr.get()); } } } }
std::string HttpAddress(const SocketAddress& address, bool secure) { return (address.port() == HttpDefaultPort(secure)) ? address.hostname() : address.ToString(); }