using System; using System.Net.Sockets; using System.Runtime.InteropServices; namespace ZeroLevel.Services.Network { public static class SocketExtensions { // Структура для настройки TCP KeepAlive (Windows) [StructLayout(LayoutKind.Sequential)] private struct TcpKeepAlive { public uint OnOff; public uint KeepAliveTime; public uint KeepAliveInterval; } // Метод расширения для настройки KeepAlive public static void SetKeepAlive(this Socket socket, bool on, uint keepAliveTime, uint keepAliveInterval) { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { // Windows-специфичная настройка через IOControl var keepAlive = new TcpKeepAlive { OnOff = on ? 1u : 0u, KeepAliveTime = keepAliveTime, // Время в миллисекундах до первой проверки KeepAliveInterval = keepAliveInterval // Интервал между проверками в миллисекундах }; int size = Marshal.SizeOf(keepAlive); IntPtr ptr = Marshal.AllocHGlobal(size); try { Marshal.StructureToPtr(keepAlive, ptr, false); byte[] buffer = new byte[size]; Marshal.Copy(ptr, buffer, 0, size); socket.IOControl(IOControlCode.KeepAliveValues, buffer, null); } finally { Marshal.FreeHGlobal(ptr); } } else { // Для Linux/MacOS используем socket options socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, on); if (on) { // На Linux эти параметры настраиваются через TCP socket options if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { // TCP_KEEPIDLE (секунды до первой проверки) socket.SetSocketOption(SocketOptionLevel.Tcp, (SocketOptionName)4, (int)(keepAliveTime / 1000)); // TCP_KEEPINTVL (интервал между проверками в секундах) socket.SetSocketOption(SocketOptionLevel.Tcp, (SocketOptionName)5, (int)(keepAliveInterval / 1000)); // TCP_KEEPCNT (количество проверок) socket.SetSocketOption(SocketOptionLevel.Tcp, (SocketOptionName)6, 9); } } } } } }