ListenPort

ListenPort

#Overview

name: ListenPort

The value of this variable can be defined or overridden in .ini config files. 1 .ini config file referencing this setting variable.

It is referenced in 25 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of ListenPort is to specify the port number on which a network service or application listens for incoming connections. This variable is commonly used in networking-related components of Unreal Engine 5, particularly for server-side functionality.

ListenPort is utilized by several Unreal Engine subsystems and modules, including:

  1. Online Subsystem: Used in the OnlineBeaconHost class for configuring network communication.
  2. HTTP Server: Employed in the HttpListener class for setting up HTTP server functionality.
  3. Steam Sockets: Used in the SteamSocketsSubsystem for managing network connections.
  4. Editor Domain Save: Utilized in the EditorDomainSaveServer for managing editor-related network communications.
  5. Datasmith and Interchange plugins: Used in worker process management for these enterprise-level tools.

The value of ListenPort is typically set in one of the following ways:

  1. Through configuration files (UPROPERTY(Config))
  2. Programmatically within the code
  3. Parsed from command-line arguments
  4. Dynamically assigned by the system (when set to 0)

ListenPort often interacts with other networking-related variables, such as IP addresses, socket objects, and network drivers.

Developers should be aware of the following when using ListenPort:

  1. Ensure the chosen port is not already in use by another application.
  2. Consider security implications when opening ports, especially on public-facing servers.
  3. Be mindful of firewall settings that may block the chosen port.
  4. For development and testing, use ports in the higher range (e.g., above 1024) to avoid conflicts with well-known services.

Best practices for using ListenPort include:

  1. Use configuration files or command-line arguments to set the port, allowing for easy changes without recompiling.
  2. Implement proper error handling for cases where the desired port is unavailable.
  3. Log the actual port used, especially when dynamically assigned.
  4. Consider using port ranges and fallback options for more robust implementations.
  5. Ensure proper cleanup and port release when the application or service terminates.

#Setting Variables

#References In INI files

Location: <Workspace>/Engine/Config/BaseEngine.ini:2386, section: [/Script/OnlineSubsystemUtils.OnlineBeaconHost]

#References in C++ code

#Callsites

This variable is referenced in the following C++ source code:

#Loc: <Workspace>/Engine/Plugins/Enterprise/DatasmithCADImporter/Source/DatasmithDispatcher/Private/DatasmithWorkerHandler.cpp:64

Scope (from outer to inner):

file
namespace    DatasmithDispatcher
function     void FDatasmithWorkerHandler::StartWorkerProcess

Source code excerpt:

	if (FPaths::FileExists(ProcessorPath))
	{
		int32 ListenPort = NetworkInterface.GetListeningPort();
		if (ListenPort == 0)
		{
			ErrorState = EWorkerErrorState::ConnectionFailed_NotBound;
			return;
		}

		FString CommandToProcess;

#Loc: <Workspace>/Engine/Plugins/Enterprise/DatasmithCADImporter/Source/DatasmithDispatcher/Private/DatasmithWorkerHandler.cpp:79

Scope (from outer to inner):

file
namespace    DatasmithDispatcher
function     void FDatasmithWorkerHandler::StartWorkerProcess

Source code excerpt:


		CommandToProcess += TEXT(" -ServerPID ") + FString::FromInt(FPlatformProcess::GetCurrentProcessId());
		CommandToProcess += TEXT(" -ServerPort ") + FString::FromInt(ListenPort);
		CommandToProcess += TEXT(" -CacheDir \"") + CachePath + TEXT('"');
		CommandToProcess += TEXT(" -CacheVersion ") + FString::FromInt(FCADToolsModule::GetCacheVersion());
		CommandToProcess += TEXT(" -EnginePluginsDir \"") + FPaths::EnginePluginsDir() + TEXT('"');
		UE_LOG(LogDatasmithDispatcher, Verbose, TEXT("CommandToProcess: %s"), *CommandToProcess);

		WorkerHandle = FPlatformProcess::CreateProc(*ProcessorPath, *CommandToProcess, true, false, false, &WorkerProcessId, 0, nullptr, nullptr);

#Loc: <Workspace>/Engine/Plugins/Interchange/Runtime/Source/Dispatcher/Private/InterchangeWorkerHandler.cpp:70

Scope (from outer to inner):

file
namespace    UE
namespace    Interchange
function     void FInterchangeWorkerHandler::StartWorkerProcess

Source code excerpt:

			if (FPaths::FileExists(ProcessorPath))
			{
				int32 ListenPort = NetworkInterface.GetListeningPort();
				if (ListenPort == 0)
				{
					ErrorState = EWorkerErrorState::ConnectionFailed_NotBound;
					return;
				}

				FString CommandToProcess;

#Loc: <Workspace>/Engine/Plugins/Interchange/Runtime/Source/Dispatcher/Private/InterchangeWorkerHandler.cpp:85

Scope (from outer to inner):

file
namespace    UE
namespace    Interchange
function     void FInterchangeWorkerHandler::StartWorkerProcess

Source code excerpt:

				CommandToProcess += TEXT(" -basedir=\"") + BaseDir + TEXT("\"");
				CommandToProcess += TEXT(" -ServerPID ") + FString::FromInt(FPlatformProcess::GetCurrentProcessId());
				CommandToProcess += TEXT(" -ServerPort ") + FString::FromInt(ListenPort);
				CommandToProcess += TEXT(" -InterchangeDispatcherVersion \"") + DispatcherCommandVersion::ToString() + TEXT('"');
				CommandToProcess += TEXT(" -ResultFolder \"") + ResultFolder + TEXT("\"");
				UE_LOG(LogInterchangeDispatcher, Verbose, TEXT("CommandToProcess: %s"), *CommandToProcess);
				WorkerHandle = FPlatformProcess::CreateProc(*ProcessorPath, *CommandToProcess, true, false, false, &WorkerProcessId, 0, nullptr, nullptr);
			}

#Loc: <Workspace>/Engine/Plugins/Online/OnlineSubsystemUtils/Source/OnlineSubsystemUtils/Private/OnlineBeaconHost.cpp:94

Scope (from outer to inner):

file
function     bool AOnlineBeaconHost::InitHost

Source code excerpt:

	if (FParse::Value(FCommandLine::Get(), TEXT("BeaconPort="), PortOverride) && PortOverride != 0)
	{
		ListenPort = PortOverride;
	}

	URL.Port = ListenPort;
	if(URL.Valid)
	{
		if (InitBase() && NetDriver)
		{
			FString Error;
			if (NetDriver->InitListen(this, URL, bReuseAddressAndPort, Error))
			{
				ListenPort = URL.Port;
				NetDriver->SetWorld(GetWorld());
				NetDriver->Notify = this;
				NetDriver->InitialConnectTimeout = BeaconConnectionInitialTimeout;
				NetDriver->ConnectionTimeout = BeaconConnectionTimeout;
				return true;
			}

#Loc: <Workspace>/Engine/Plugins/Online/OnlineSubsystemUtils/Source/OnlineSubsystemUtils/Public/OnlineBeaconHost.h:32

Scope (from outer to inner):

file
class        class AOnlineBeaconHost : public AOnlineBeacon

Source code excerpt:

	/** Configured listen port for this beacon host */
	UPROPERTY(Config)
	int32 ListenPort;

	/**
	 * Whether to configure the listening socket to allow reuse of the address and port. If this is true, be sure no other
	 * servers can run on the same port, otherwise this can lead to undefined behavior since packets will go to two servers.
	 */
	UPROPERTY(Config)

#Loc: <Workspace>/Engine/Plugins/Online/OnlineSubsystemUtils/Source/OnlineSubsystemUtils/Public/OnlineBeaconHost.h:66

Scope (from outer to inner):

file
class        class AOnlineBeaconHost : public AOnlineBeacon
function     virtual int32 GetListenPort

Source code excerpt:

	 * @return beacon listen port
	 */
	virtual int32 GetListenPort() { return ListenPort; }

	/**
	 * Register a beacon host and its client actor factory
	 *
	 * @param NewHostObject new 
	 */

#Loc: <Workspace>/Engine/Plugins/Runtime/Steam/SteamSockets/Source/SteamSockets/Private/SteamSocketsSubsystem.cpp:749

Scope (from outer to inner):

file
function     void FSteamSocketsSubsystem::OnServerLoginComplete

Source code excerpt:

		{
			// Push in the new valid information.
			int32 ListenPort = DelayedListener.Socket->BindAddress.GetPlatformPort();
			TSharedPtr<FInternetAddrSteamSockets> ListenerAddress = StaticCastSharedRef<FInternetAddrSteamSockets>(SteamIdentityAddr->Clone());
			ListenerAddress->SetPlatformPort(ListenPort);

			// Update the socket and netdriver addresses
			DelayedListener.Socket->BindAddress = *ListenerAddress;
			SteamNetDriver->LocalAddr = ListenerAddress;

			// Actually start the listen call

#Loc: <Workspace>/Engine/Plugins/UbaController/Source/UbaController/Private/UbaHordeAgentManager.cpp:294

Scope (from outer to inner):

file
function     void FUbaHordeAgentManager::ThreadAgent

Source code excerpt:

		}

		uint32 ListenPort = 7001;

		// Start the UBA Agent that will connect to us, requesting for work
		const std::string ListenPortArg = "-listen=" + std::to_string(ListenPort);

		const char* UbaAgentArgs[] =
		{
			ListenPortArg.c_str(),
			"-nopoll",				// -nopoll recommended when running on remote Horde agents to make sure they exit after completion. Otherwise, it keeps running.
			"-listenTimeout=5",		// Agent will wait 5 seconds for this thread to connect (Server_AddClient does the connect)

#Loc: <Workspace>/Engine/Plugins/UbaController/Source/UbaController/Private/UbaHordeAgentManager.cpp:322

Scope (from outer to inner):

file
function     void FUbaHordeAgentManager::ThreadAgent

Source code excerpt:

		const FString& IpAddress = Agent->GetMachineInfo().Ip;
		auto IpAddressStr = StringCast<uba::tchar>(*IpAddress);
		const bool bAddClientSuccess = Server_AddClient(UbaServer, IpAddressStr.Get(), ListenPort, nullptr);

		if (!bAddClientSuccess)
		{
			UE_LOG(LogUbaController, Display, TEXT("Server_AddClient(%s:%d) failed"), *IpAddress, ListenPort);
			return;
		}

		// Log remote execution
		FString UbaAgentCmdArgs = TEXT("UbaAgent.exe");
		for (const char* Arg : UbaAgentArgs)

#Loc: <Workspace>/Engine/Plugins/UbaController/Source/UbaController/Private/UbaHordeAgentManager.cpp:337

Scope (from outer to inner):

file
function     void FUbaHordeAgentManager::ThreadAgent

Source code excerpt:

			UbaAgentCmdArgs += ANSI_TO_TCHAR(Arg);
		}
		UE_LOG(LogUbaController, Log, TEXT("Remote execution on Horde machine [%s:%d]: %s"), *IpAddress, ListenPort, *UbaAgentCmdArgs);

		MachineCoreCount = MachineInfo.LogicalCores;
		EstimatedCoreCount += MachineCoreCount;
		ActiveCoreCount += MachineCoreCount;
	}

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/EditorDomain/EditorDomainSave.cpp:254

Scope (from outer to inner):

file
function     bool FEditorDomainSaveServer::TryInitialize

Source code excerpt:


	TSharedPtr<FJsonObject> SettingsObject;
	if (!TryRefreshAuthority(nullptr /* bOutOwnsSettingFile */, &SettingsObject, &ListenPort))
	{
		// Log statement sent by TryRefreshAuthority
		return false;
	}

	ISocketSubsystem* SocketSubsystem = ISocketSubsystem::Get();

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/EditorDomain/EditorDomainSave.cpp:267

Scope (from outer to inner):

file
function     bool FEditorDomainSaveServer::TryInitialize

Source code excerpt:

	}
	TSharedRef<FInternetAddr> ListenAddr = SocketSubsystem->GetLocalBindAddr(*GLog);
	ListenAddr->SetPort(ListenPort);
	ListenSocket = SocketSubsystem->CreateSocket(NAME_Stream, TEXT("FEditorDomainSaveServer tcp-listen"),
		ListenAddr->GetProtocolType());
	if (!ListenSocket)
	{
		UE_LOG(LogEditorDomainSave, Error, TEXT("CreateSocket failed, aborting creation of EditorDomainServer."));
		return false;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/EditorDomain/EditorDomainSave.cpp:292

Scope (from outer to inner):

file
function     bool FEditorDomainSaveServer::TryInitialize

Source code excerpt:

		return false;
	}
	ListenPort = ListenSocket->GetPortNo();
	ListenAddr->SetPort(ListenPort);
	UE_LOG(LogEditorDomainSave, Display, TEXT("EditorDomainSaveServer is listening for client connections on %s."),
		*ListenAddr->ToString(true));

	SettingsObject->SetNumberField(SettingNames::ListenPortFieldName, ListenPort);
	if (!TryWriteServerSettings(SettingsObject))
	{
		UE_LOG(LogEditorDomainSave, Warning,
			TEXT("Failed to write ServerSettings file %s, aborting creation of EditorDomainServer."),
			*GetServerSettingsFilename());
		return false;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/EditorDomain/EditorDomainSave.cpp:321

Scope (from outer to inner):

file
function     bool FEditorDomainSaveServer::TryRefreshAuthority

Source code excerpt:

	}

	bool bIsInitialAcquisition = ListenPort == 0;
	const TCHAR* ErrorActionDesc = bIsInitialAcquisition
		? TEXT("aborting creation")
		: TEXT("relinquishing ownership and shutting down");

	int32 ServerProcessId = 0;
	int32 LocalListenPort = 0;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/EditorDomain/EditorDomainSave.cpp:369

Scope (from outer to inner):

file
function     bool FEditorDomainSaveServer::TryRefreshAuthority

Source code excerpt:

	}

	if (!bIsInitialAcquisition && LocalListenPort != ListenPort)
	{
		UE_LOG(LogEditorDomainSave, Error,
			TEXT("Listen port has changed from %d to %d. Change in listen port is unsupported; %s."),
			ListenPort, LocalListenPort, ErrorActionDesc);
		return false;
	}
	if (OutListenPort)
	{
		*OutListenPort = LocalListenPort;
	}

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/EditorDomain/EditorDomainSave.cpp:1127

Scope (from outer to inner):

file
function     bool FEditorDomainSaveClient::TryConnectProcess

Source code excerpt:

	}

	// We are not successful until we the server has written the ListenPort for us to read; retry the read again on next tick
	return false;
}

bool FEditorDomainSaveClient::TryReadConnectionData(uint32& OutLocalServerProcessId, uint32& OutLocalServerListenPort,
	FDateTime& OutServerSettingsTimestamp)
{

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/EditorDomain/EditorDomainSave.h:146

Scope (from outer to inner):

file
class        class FEditorDomainSaveServer

Source code excerpt:

	int32 CreatorProcessId = 0;
	/** The port to listen on. */
	int32 ListenPort = 0;
	/** True if the server was idle (no pending messages, no pending packages) in its previous tick. */
	bool bIdle = false;
	/** True if any client has so-far connected. Used to decide abdication. */
	bool bHasEverConnected = false;
	/** True if the server has abdicated and should shutdown. */
	bool bAbdicated = false;

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/GameInstance.cpp:551

Scope (from outer to inner):

file
function     FGameInstancePIEResult UGameInstance::StartPlayInEditorGameInstance

Source code excerpt:

		{
			// Add port
			uint32 ListenPort = 0;
			uint16 ServerPort = 0;
			if (Params.EditorPlaySettings->GetServerPort(ServerPort))
			{
				ListenPort = ServerPort;
			}

			// Start a listen server
			ensureMsgf(EnableListenServer(true, ListenPort), TEXT("Starting Listen Server for Play in Editor failed!"));
		}

		SlowTask.EnterProgressFrame(10, NSLOCTEXT("UnrealEd", "PIEBeginPlay", "Starting PIE (Begin play)..."));
		PlayWorld->BeginPlay();

		SlowTask.EnterProgressFrame(10);

#Loc: <Workspace>/Engine/Source/Runtime/Online/HTTPServer/Private/HttpListener.cpp:15

Scope (from outer to inner):

file
function     FHttpListener::FHttpListener

Source code excerpt:

{ 
	check(InListenPort > 0);
	ListenPort = InListenPort;
	Router = MakeShared<FHttpRouter>();
}

FHttpListener::~FHttpListener() 
{ 
	check(!ListenSocket);

#Loc: <Workspace>/Engine/Source/Runtime/Online/HTTPServer/Private/HttpListener.cpp:60

Scope (from outer to inner):

file
function     bool FHttpListener::StartListening

Source code excerpt:

	// Bind to config-driven address
	TSharedRef<FInternetAddr> BindAddress = SocketSubsystem->CreateInternetAddr();
	Config = FHttpServerConfig::GetListenerConfig(ListenPort);
	if (0 == Config.BindAddress.Compare(TEXT("any"), ESearchCase::IgnoreCase))
	{
		BindAddress->SetAnyAddress();
	}
	else if (0 == Config.BindAddress.Compare(TEXT("localhost"), ESearchCase::IgnoreCase))
	{

#Loc: <Workspace>/Engine/Source/Runtime/Online/HTTPServer/Private/HttpListener.cpp:77

Scope (from outer to inner):

file
function     bool FHttpListener::StartListening

Source code excerpt:

			UE_LOG(LogHttpListener, Error,
				TEXT("HttpListener detected invalid bind address (%s:%u)"),
				*Config.BindAddress, ListenPort);
			return false;
		}
	}

	if (!BindAddress->IsPortValid(ListenPort))
	{
		UE_LOG(LogHttpListener, Error,
			TEXT("HttpListener detected invalid port %u"),
			ListenPort, *Config.BindAddress, ListenPort);
		return false;
	}
	BindAddress->SetPort(ListenPort);

	if (Config.bReuseAddressAndPort)
	{
		NewSocket->SetReuseAddr(true);
	}

#Loc: <Workspace>/Engine/Source/Runtime/Online/HTTPServer/Private/HttpListener.cpp:136

Scope (from outer to inner):

file
function     void FHttpListener::StopListening

Source code excerpt:

	{
		UE_LOG(LogHttpListener, Log,
			TEXT("HttListener stopping listening on Port %u"), ListenPort);

		ListenSocket.Reset();
	}
	bIsListening = false;

	const bool bRequestGracefulExit = true;

#Loc: <Workspace>/Engine/Source/Runtime/Online/HTTPServer/Private/HttpListener.cpp:220

Scope (from outer to inner):

file
function     void FHttpListener::AcceptConnections

Source code excerpt:

			IncomingConnection->SetNonBlocking(true);
			TSharedPtr<FHttpConnection> Connection = 
				MakeShared<FHttpConnection>(IncomingConnection, Router, ListenPort, NumConnectionsAccepted++);
			Connections.Add(Connection);
		}
	}
}

void FHttpListener::TickConnections(float DeltaTime)

#Loc: <Workspace>/Engine/Source/Runtime/Online/HTTPServer/Private/HttpListener.h:98

Scope (from outer to inner):

file
class        class FHttpListener final

Source code excerpt:


	/** The port on which the binding socket listens */
	uint32 ListenPort = 0;

	/** The binding socket which accepts incoming connections */
	FUniqueSocket ListenSocket;

	/** The mechanism that routes requests to respective handlers  */
	TSharedPtr<FHttpRouter> Router = nullptr;