75 lines
2.9 KiB
C#
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 : "";
|
|
}
|
|
}
|