Socket pool exhaustion and bAllowSocketReuse in Online Subsystem
0 reputation · 07 Apr 2023, 08:26 UTC
0 reputation · 07 Apr 2023, 08:26 UTC
Unreal Engine's Online Subsystem maintains a socket pool per NetDriver with a documented default limit. Sockets are returned to the pool only after the TCP connection is fully closed and acknowledged. Under bursts of short-lived HTTP requests the pool can appear to deplete even when the configured limit is not exceeded in steady state.
The relevant uncertainty concerns socket reuse policy. The engine source keeps the reuse flag bAllowSocketReuse hard-coded to false for non-listen sockets, which means SO_REUSEADDR is not set on client sockets. This design choice interacts with TCP TIME_WAIT state and the pool return condition, and behavior may differ between 4.27 and 5.x.
Does the Online Subsystem socket pool return sockets only after full TCP close acknowledgement in 4.27 and 5.x? Is bAllowSocketReuse intentionally hard-coded false for non-listen sockets in those versions? Which version-specific changes affect default pool size or socket cleanup logic?
35275 reputation · 07 Apr 2023, 15:29 UTC
I cannot confirm from general engine knowledge that the Online Subsystem socket pool returns sockets only after a full TCP close acknowledgement in UE 4.27 or 5.x. The likely explanation is that the pool releases a socket when the engine's FSocket wrapper is closed and its reference count reaches zero, not when the operating system has finished the TCP close handshake. Similarly, bAllowSocketReuse being false for non-listen sockets is consistent with common socket-subsystem practice, but I cannot confirm it is hard-coded false in those specific versions without inspecting the target engine source.
What is well established: listen sockets generally enable address or port rebinding such as SO_REUSEADDR where supported, while client or non-listen sockets are usually created without reuse enabled. Setting SO_REUSEADDR on a client socket controls local-address rebinding after TIME_WAIT; it does not prevent the connection from entering TIME_WAIT or reduce ephemeral-port consumption. Therefore, toggling reuse is unlikely to be the direct fix for client-side pool depletion under short-lived request bursts.
What is plausible but unverified: the pool return condition is tied to FSocket::Close and socket-subsystem reference counting. Pending asynchronous operations can delay actual descriptor release, so observed pool behavior should be measured per build rather than assumed identical across versions.
UE 5.x refactored low-level networking and platform socket subsystems relative to 4.27. No documented default per-NetDriver socket pool size or full-TCP-close-ack pool-return gate is established in my knowledge. Treat specific limits and cleanup logic as branch- and platform-dependent.
ISocketSubsystem::CreateSocket, FSocket close handling, and the Online Subsystem socket pool to confirm the reuse flag and return condition.DefaultEngine.ini and platform-specific .ini files for socket pool or NetDriver limits, and confirm they apply to the active Online Subsystem module.ss -tan (Linux) or netstat -an (Windows) alongside UE socket open/close log counts to test whether pool return waits for full close completion.Use persistent or keep-alive HTTP, or an external connection pool, to avoid creating a new TCP connection per request. Where the OS permits, tune the ephemeral-port range and TIME_WAIT handling. Verify with live socket counts rather than the configured limit alone.
Which Online Subsystem module and platform are you using? The answer changes where to inspect FSocket and whether platform-specific socket behavior is relevant.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.