Streamingle_URP/Assets/Scripts/Streamdeck/NetworkInterfaceUtil.cs

75 lines
2.9 KiB
C#

using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
/// <summary>
/// 활성 네트워크 어댑터의 IPv4 주소를 열거하고, 선호 주소를 해석하는 유틸리티.
/// PC에 NIC이 여러 개(유선/무선/Hyper-V/VPN 등)일 때 서버가 사용/표시할 IP를
/// 사용자가 명시적으로 고를 수 있도록 돕는다.
/// </summary>
public static class NetworkInterfaceUtil
{
public struct Adapter
{
public string name; // 어댑터 이름 (예: "이더넷", "Wi-Fi")
public string ip; // IPv4 주소 문자열
}
/// <summary>
/// 활성(Up) IPv4 어댑터 목록을 반환한다. 루프백/APIPA(169.254.x.x)는 제외.
/// 기본 게이트웨이가 있는 어댑터(실제 LAN/인터넷 연결)를 앞쪽에 정렬하여
/// Hyper-V/VPN 같은 가상 어댑터보다 우선 노출한다.
/// </summary>
public static List<Adapter> GetAdapters()
{
var withGateway = new List<Adapter>();
var withoutGateway = new List<Adapter>();
try
{
foreach (var ni in NetworkInterface.GetAllNetworkInterfaces())
{
if (ni.OperationalStatus != OperationalStatus.Up) continue;
if (ni.NetworkInterfaceType == NetworkInterfaceType.Loopback) continue;
var props = ni.GetIPProperties();
bool hasGateway = props.GatewayAddresses.Any(g =>
g.Address != null &&
g.Address.AddressFamily == AddressFamily.InterNetwork &&
!g.Address.Equals(IPAddress.Any));
foreach (var addr in props.UnicastAddresses)
{
if (addr.Address.AddressFamily != AddressFamily.InterNetwork) continue;
if (IPAddress.IsLoopback(addr.Address)) continue;
byte[] b = addr.Address.GetAddressBytes();
if (b[0] == 169 && b[1] == 254) continue; // APIPA(자동 사설 IP) 제외
var adapter = new Adapter { name = ni.Name, ip = addr.Address.ToString() };
(hasGateway ? withGateway : withoutGateway).Add(adapter);
}
}
}
catch { }
withGateway.AddRange(withoutGateway);
return withGateway;
}
/// <summary>
/// 선호 주소(preferred)가 현재 유효한 어댑터 IP면 그대로 사용하고,
/// 비었거나 더 이상 존재하지 않으면 자동 선택(첫 번째 = 게이트웨이 우선)한다.
/// 사용 가능한 IPv4가 전혀 없으면 빈 문자열.
/// </summary>
public static string ResolveHostAddress(string preferred)
{
var adapters = GetAdapters();
if (!string.IsNullOrEmpty(preferred) && adapters.Any(a => a.ip == preferred))
return preferred;
return adapters.Count > 0 ? adapters[0].ip : "";
}
}