using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text;

namespace CommonNetwork_ICE.Util
{
    /// <summary>
    /// 网络工具类
    /// </summary>
    public class NetUtil
    {
        /// <summary>
        /// 获取本机IP
        /// </summary>
        /// <returns>本机IP</returns>
        public static IPAddress getLocalIp()
        {
            IPHostEntry host;
            host = Dns.GetHostEntry(Dns.GetHostName());
            foreach (IPAddress ip in host.AddressList)
            {
                if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                {
                    return ip;
                }
            }
            return null;
        }

        /// <summary>
        /// 检测端口是否被占用
        /// </summary>
        /// <param name="port">端口</param>
        /// <returns>是否被占用</returns>
        public static bool CheckPortInUse(IPAddress ip, int port)
        {
            bool inUse = CheckTcpPortInUse(ip, port);
            if (inUse)
            {
                return true;
            }
            return CheckUdpPortInUse(ip, port);
        }

        /// <summary>
        /// 检测TCP端口是否被占用
        /// </summary>
        /// <param name="port">端口</param>
        /// <returns>是否被占用</returns>
        public static bool CheckTcpPortInUse(IPAddress ip, int port)
        {
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint ipAddress = new IPEndPoint(ip, port);
            try
            {
                socket.Bind(ipAddress);
            }
            catch (SocketException se)
            {
                return true;
            }
            finally
            {
                if (socket != null)
                {
                    socket.Close();
                }
            }
            return false;
        }

        /// <summary>
        /// 检测UDP端口是否被占用
        /// </summary>
        /// <param name="port">端口</param>
        /// <returns>是否被占用</returns>
        public static bool CheckUdpPortInUse(IPAddress ip, int port)
        {
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            IPEndPoint ipAddress = new IPEndPoint(ip, port);
            try
            {
                socket.Bind(ipAddress);
            }
            catch (SocketException se)
            {
                return true;
            }
            finally
            {
                if (socket != null)
                {
                    socket.Close();
                }
            }
            return false;
        }

        /// <summary>
        /// 检测可用端口,通过基准端口(每次+1)查找可用端口
        /// </summary>
        /// <param name="port">基准端口</param>
        /// <returns>可用端口,无可用端口返回-1</returns>
        public static int GetUsablePort(int port)
        {
            IPAddress ip = getLocalIp();
            for (int i = port; i < 65535; i++)
            {
                if (!CheckPortInUse(ip, port))
                {
                    return i;
                }
            }
            return -1;
        }
    }
}