分享
 
 
 

使用C#查询路由接口,同时小议一些.net 2.0的诡异API

王朝c#·作者佚名  2008-05-31
窄屏简体版  字體: |||超大  

有时候我们希望知道程序正在使用那个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("www.google.com")[0],

1000);

IPEndPoint ep = QueryRoutingInterface(s, remoteEP);

Console.WriteLine(remoteEP);

Console.WriteLine(ep);

}

catch (SocketException e)

{

Console.WriteLine(e);

Console.WriteLine(e.ErrorCode);

}

}

}

程序的核心是QueryRoutingInterface方法,代码相当的简单,我就不多做解释了。

http://www.cnblogs.com/ncindy/archive/2007/01/02/610148.html

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有