国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

使用C#查詢路由接口,同時小議一些.net 2.0的詭異API

2019-11-18 16:45:40
字體:
來源:轉載
供稿:網友

有時候我們希望知道程序正在使用那個ip地址連接到遠程的服務器(類似pathping命令返回的第一個結果,P2P應用中尤其多見),文末的代碼可以完成這個任務

寫完這段代碼之后,我對.net API的設計有些不滿了。

首先就是Socket類的IOControl方法,該方法脫胎于Winsock2 API的WSAIoctl函數。對于基于C語言的Winsock2 API,設計出WSAIoctl顯得還合情合理,雖然冗長的參數列表很是嚇人,但是對于面向對象的C#,居然還需要使用byte[]這些弱類型的數據結構來做參數,實在是有些匪夷所思了,我覺得Socket類應該對IOControl進行充分的包裝,以便沒有Win32 API經驗的用戶更好的使用。


接著是IPEndPoint的序列化形式SocketAddress類,這個類明顯的與sockaddr structure一樣,不同的是,它比sockaddr structure更加難以使用。它提供了一個象數組一樣的索引器,允許用戶以[]運算符獲取其中的byte元素,但是卻不提供方法簡便的將其中的內容復制到一個byte[]中供Socket.IOControl調用,竟然需要客戶自己使用循環來調用,實在傻的可以。


最后是IPEndPoint,它居然需要實例化之后才能調用Create成員函數把一個SocketAddress實例反序列化成一個IPEndPoint對象,我暈,為啥不是靜態的呢?看了這個Create方法的代碼之后,我發現完全沒有必要將其做成成員函數(為了證明靜態方法的可行,我在文中創建了一個CreateIPEndPoint靜態方法,并用它替換了IPEndPoint.Create成員方法),不知道為了使這個方法看起來更像是成員方法還是其他什么原因,SocketAddress的AddressFamily居然必須和IPEndPoint實例的AddressFamily一致,否則就拋出異常,狂暈,人家反序列化還得看你一個不知所謂的對象的臉色,真是慘。

以上是我的觀點,歡迎大家一起議議。

using System;
using System.Net.Sockets;

using System.Net;

 

 

class PRogram

{

    static IPEndPoint QueryRoutingInterface(Socket sock,

                                            IPEndPoint remoteEP)

    {

        SocketAddress sa = remoteEP.Serialize();

 

        byte[] addrBytes = new byte[sa.Size];

 

        for (int i = 0; i < sa.Size; i++)

        {

            addrBytes[i] = sa[i];

        }

 

        byte[] outBytes = new byte[addrBytes.Length];

 

        sock.IOControl(IOControlCode.RoutingInterfaceQuery,

                                   addrBytes,

                                   outBytes);

 

        for (int i = 0; i < sa.Size; i++)

        {

            sa[i] = outBytes[i];

        }

 

 

        EndPoint ep = CreateIPEndPoint(sa);//remoteEP.Create(sa);

 

        return (IPEndPoint)ep;

    }

 

    /// <summary>

    /// 根據SocketAddress創建IPEndPoint

    /// </summary>

    /// <remarks>該函數從IPEndPoint的Create方法反編譯出來</remarks>

    /// <param name="socketAddress"></param>

    /// <returns></returns>

    public static IPEndPoint CreateIPEndPoint(SocketAddress socketAddress)

    {

        //if (socketAddress.Family != this.AddressFamily)

        //{

        //    throw new ArgumentException(SR.GetString("net_InvalidAddressFamily",

        //        new object[] { socketAddress.Family.ToString(),

        //            base.GetType().FullName, this.AddressFamily.ToString() }),

        //            "socketAddress");

        //}

 

        if (socketAddress.Size < 8)

        {

            //throw new ArgumentException(SR.GetString("net_InvalidSocketAddressSize",

            //    new object[] { socketAddress.GetType().FullName,

            //        base.GetType().FullName }),

            //        "socketAddress");

 

            throw new ArgumentException();

        }

 

//if (this.AddressFamily == AddressFamily.InterNetworkV6)

        if (socketAddress.Family == AddressFamily.InterNetworkV6)

        {

            byte[] buffer1 = new byte[0x10];

            for (int num1 = 0; num1 < buffer1.Length; num1++)

            {

                buffer1[num1] = socketAddress[num1 + 8];

            }

            int num2 = ((socketAddress[2] << 8) & 0xff00) | socketAddress[3];

            long num3 = (((socketAddress[0x1b] << 0x18)

                + (socketAddress[0x1a] << 0x10))

                + (socketAddress[0x19] << 8)) +

                        socketAddress[0x18];

            return new IPEndPoint(new IPAddress(buffer1, num3), num2);

        }

 

        int num4 = ((socketAddress[2] << 8) & 0xff00) | socketAddress[3];

 

        long num5 = ((((socketAddress[4] & 0xff)

            | ((socketAddress[5] << 8) & 0xff00))

            | ((socketAddress[6] << 0x10) & 0xff0000))

            | (socketAddress[7] << 0x18)) & ((long)0xffffffff);

 

        return new IPEndPoint(num5, num4);

    }

 

 

    static void Main(string[] args)

    {

        try

        {

            Socket s = new Socket(AddressFamily.InterNetwork,

                                  SocketType.Dgram,

                                  ProtocolType.Udp);

 

            s.Bind(new IPEndPoint(IPAddress.Any, 10001));

 

            IPEndPoint remoteEP = new IPEndPoint(

                Dns.GetHostAddresses("],

                1000);

 

            IPEndPoint ep = QueryRoutingInterface(s, remoteEP);

            Console.WriteLine(remoteEP);

            Console.WriteLine(ep);

        }

        catch (SocketException e)

        {

            Console.WriteLine(e);

            Console.WriteLine(e.ErrorCode);

        }

    }

}


程序的核心是QueryRoutingInterface方法,代碼相當的簡單,我就不多做解釋了。
http://m.survivalescaperooms.com/ncindy/archive/2007/01/02/610148.html


上一篇:C#連接mysql

下一篇:C#中常用到的JS

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 新昌县| 夏河县| 九台市| 嘉定区| 万全县| 贵州省| 宜州市| 政和县| 马公市| 垦利县| 天峻县| 乐东| 三门县| 新津县| 长葛市| 益阳市| 涿州市| 富蕴县| 台东县| 平定县| 军事| 县级市| 大埔区| 长武县| 临夏市| 开江县| 东台市| 石阡县| 上栗县| 庄浪县| 海宁市| 平果县| 共和县| 元朗区| 贵南县| 桐梓县| 宝山区| 青海省| 泉州市| 抚宁县| 大埔县|