예제 #1
0
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;
		}
	}
}
예제 #2
0
//----------------------------------------------------------------------------
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() );
	}
}
예제 #4
0
//----------------------------------------------------------------------------
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;
}
예제 #5
0
//----------------------------------------------------------------------------
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());
	}
}
예제 #6
0
//----------------------------------------------------------------------------
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;
}
예제 #7
0
//----------------------------------------------------------------------------
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;
}
예제 #8
0
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());
			}
		}
	}
}
예제 #9
0
	std::string HttpAddress(const SocketAddress& address, bool secure) {
		return (address.port() == HttpDefaultPort(secure))
			? address.hostname() : address.ToString();
	}