Esempio n. 1
0
bool UNetworkManager::Start(int32 InPortNum) // Restart the server if configuration changed
{
	if (InPortNum == this->PortNum && this->bIsListening) return true; // Already started

	if (ConnectionSocket) // Release previous connection
	{
		ConnectionSocket->Close();
		ConnectionSocket = NULL;
	}

	if (TcpListener) // Delete previous configuration first
	{
		UE_LOG(LogUnrealCV, Warning, TEXT("Stop previous server"));
		TcpListener->Stop(); // TODO: test the robustness, will this operation successful?
		delete TcpListener;
	}

	this->PortNum = InPortNum; // Start a new TCPListener
	FIPv4Address IPAddress = FIPv4Address(0, 0, 0, 0);
	// int32 PortNum = this->PortNum; // Make this configuable
	FIPv4Endpoint Endpoint(IPAddress, PortNum);

	FSocket* ServerSocket = FTcpSocketBuilder(TEXT("FTcpListener server")) // TODO: Need to realease this socket
		// .AsReusable()
		.BoundToEndpoint(Endpoint)
		.Listening(8);

	if (ServerSocket)
	{
		int32 NewSize = 0;
		ServerSocket->SetReceiveBufferSize(2 * 1024 * 1024, NewSize);
	}
	else
	{
		this->bIsListening = false;
		UE_LOG(LogUnrealCV, Warning, TEXT("Cannot start listening on port %d, Port might be in use"), PortNum);
		return false;
	}

	TcpListener = new FTcpListener(*ServerSocket);
	// TcpListener = new FTcpListener(Endpoint); // This will be released after start
	// In FSocket, when a FSocket is set as reusable, it means SO_REUSEADDR, not SO_REUSEPORT.  see SocketsBSD.cpp
	TcpListener->OnConnectionAccepted().BindUObject(this, &UNetworkManager::Connected);
	if (TcpListener->Init())
	{
		this->bIsListening = true;
		UE_LOG(LogUnrealCV, Warning, TEXT("Start listening on %d"), PortNum);
		return true;
	}
	else
	{
		this->bIsListening = false;
		UE_LOG(LogUnrealCV, Error, TEXT("Can not start listening on port %d"), PortNum);
		return false;
	}
}