• 网络编程


    using System;

    using System.Collections.Generic;

    using System.Text;

    using System.Net;

    using System.Threading;

    using System.Net.Sockets;

    namespace ConsoleApplication1

    {

        public  class AddressHelper

        {

            /// <summary>

            /// 获取主机IPv4

            /// </summary>

            /// <returns></returns>

            public IPAddress[] GetLocalhostIPv4Address()

            {

                //获取主机名

                string localhostName = Dns.GetHostName();

                //通过主机名获取主机地址信息

                IPHostEntry host = Dns.GetHostEntry(localhostName);

                List<IPAddress> addresses = new List<IPAddress>();

                foreach (IPAddress ip in host.AddressList)

                {

                    if (ip.AddressFamily==System.Net.Sockets.AddressFamily.InterNetwork)

                    {

                        addresses.Add(ip);

                    }

                }

                return addresses.ToArray();

            }

            /// <summary>

            /// 获取一个网络端点表示为IP地址和端口号

            /// </summary>

            /// <returns></returns>

            public  IPEndPoint GetRemoteMachineIPEndPoint()

            {

                IPEndPoint iep = null;

                try

                {

                    Console.WriteLine("请输入远程主机的IP:");

                    IPAddress address = IPAddress.Parse(Console.ReadLine());

                    Console.WriteLine("请输入远程主机打开的端口号:");

                    int port = Convert.ToInt32(Console.ReadLine());

                    if (port > 65535 || port < 1024)

                    {

                        throw new Exception("端口号应该在[1024,65535]之间");

                    }

                    //ip终结点

                    iep = new IPEndPoint(address, port);

                }

                    //将空引用传递

                catch (ArgumentNullException)

                {

                    Console.WriteLine("输入数据有误!不允许空");

                }

                    //数据格式不正确

                catch (FormatException)

                {

                    Console.WriteLine("输入数据有误!格式不正确");

                }

                catch (Exception ex)

                {

                    Console.WriteLine(ex.Message);

                }

                return iep;

            }

            /*1、我们可以使用哪个端口?

             * 在实际开发中,经常为某个网络服务动态指定一个端口,为了避免与某些重要的网络服务程序冲突(比如80端口固定为Web服务器使用的)

             * 通常要求这个端口位于[1024,65535]之间

             * 我们如何选取一个没有被占用的端口呢?     

             * IPAddress.Any这个特殊的地址可以派上用场,当一个套接字对象绑定一个IPAddress.Any对象时,windows会为其自动分配一个未被占用的端口号

             * 当套接字不在使用时被回收,可以重复使用

             * 由此可以得到思路:

             * 创建一个套接字对象,让他绑定到IPAddress.Any对象,提取系统分配给的端口,然后再销毁此套接字对象。

             * Socket对象实现了IDisposable接口所以使用using关键字来自动回收其占用的资源

             * 为了防止2个网络程序(或者2个线程)同时调用可用端口的情况吗?

             * 这时,无法保证此方法的两次调用一定返回不同的端口。如果两个 Socket 对象尝试绑定到同一个 IPEndPoint ,将会引发一个 SocketException 异步。

             * 为此,我们需要一个能跨越进程边界的线程同步手段。命名的互斥同步对象 Mutex 可以解决这个问题

             */

            /// <summary>

            /// 获取本机当前可用的端口号,此方法是线程安全的

            /// </summary>

            /// <returns></returns>

            public int GetOneAvailableInLocalhost()

            {

                Mutex mtx = new Mutex(false, "ConsoleApplication1.AddressHelper.GetOneAvailablePort");

                try

                {

                    mtx.WaitOne();

                    IPEndPoint ep = new IPEndPoint(IPAddress.Any, 0);

                    using (Socket tempSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))

                    {

                        tempSocket.Bind(ep);

                        IPEndPoint iep = tempSocket.LocalEndPoint as IPEndPoint;

                        return iep.Port;

                    }

                }

                catch (Exception)

                {

                    throw;

                }

                finally

                {

                    mtx.ReleaseMutex();

                }

            }

        }

    }

  • 相关阅读:
    luogu P3376 【模板】网络最大流
    cogs 774. [USACO Open09] 捉迷藏
    1002. A+B for Polynomials (25) (浮点数判0)
    1001. A+B Format (20) (%0nd)
    7-28 搜索树判断(25 分)
    7-27 家谱处理(30 分)
    7-26 Windows消息队列(25 分)(堆排序)
    7-25 朋友圈(25 分)(并查集)
    7-24 树种统计(25 分)(二叉排序的应用)
    7-23 还原二叉树(25 分)
  • 原文地址:https://www.cnblogs.com/hailiang2013/p/2846431.html
Copyright © 2020-2023  润新知