none
C# 调用uPnP的API速度太慢 RRS feed

  • 常规讨论

  • 先添加引用(COM组件):
    NATUPNPLib
    UPNPLib

    如下代码(仅为使用方法):

    using NATUPNPLib;
    using UPNPLib;

    UPnPNATClass UPnPNATObj = new UPnPNATClass();
    IStaticPortMappingCollection mapping = UPnPNATObj.StaticPortMappingCollection;
    mapping.Add(ExternalPort|int, WhichProtocol|string, InternalPort|int, MachineIP|string, true|bool, NameString);

    这样执行相关代码可以为路由器添加uPnP的静态端口映射,方法可以正确执行。
    但是有些时候,不明的原因使这段代码第一次执行会失败,这个时候紧接着再执行一次就会成功。
    另外,这段代码似乎会block当前线程,并且执行速度奇慢(慢到无法忍受)。

    以上现象全部不明原因,我也不清楚uPnP的API的原理,但是从uPnP的协议来看是要做多次数据交换,有几次是使用HTTP的。


    请问,此API执行如此之慢,是因为COM组件本身还是调用方法,或者为什么会有以上奇怪现象?

    2010年7月26日 3:56

全部回复

  • 其他语言调用快么?

    避免阻塞界面可以用异步或者线程调用来完成。

     


    family as water
    2010年7月26日 9:12
  • 直接利用操作系统调用 UPnP API 也很慢。从 Computer 打开一个 UPnP 设备属性需要将近 20 秒。添加端口也需要好几秒。貌似本来就很慢。

    UPnP 大部分数据走 HTTP,如果本身设备忙,也会减慢速度。

    楼主可以把自己的程序速度和直接用 Windows 操作的速度作对比。不过我要说明的是并不是 COM 慢,这个速度与 COM 无关。


    Mark Zhou
    2010年7月26日 9:13
  • 我后来也是用另一个线程在界面还未显示时就去进行端口映射,这样弥补一下对用户体验的影响。

    可是,还是能见到很多应用程序用UPnP很快的。

    按照楼下的说法,应该是语言无关喽?

    和跨平台调用COM也没有关系的话,那就只能想各种办法在正式的工作之前完成uPnP的步骤。

    2010年7月26日 14:27
  • 我看到很多需要NAT的应用程序用uPnP来做,有不少效率很高的,不知什么原因。

    我做过试验,如果一开始就把防火墙关掉,抓包监听的话,发现果然这些程序的网络通信效率不一样。

    所以我猜测它们可能自己实现uPnP协议而不是利用这个COM。

    不过,我个人比较怀疑,难道第三方会做出比微软更有效率的事情? 毕竟uPnP是微软也曾热情高涨的支持的。
    2010年7月26日 14:31
  • UPnP 的效率问题也可能和设备有关的,目前我暂不清楚第三方怎么实现 UPnP 通信的,我在我的设备 (TPLINK Wireless N Router) 上做实验,打开属性就很慢 (Windows 7 x64),添加 NAT 更是慢 (点击确定之后,另外的线程会去做这个事情)。难道第三方是直接去 HTTP GET/POST 的?
    Mark Zhou
    2010年7月27日 9:41
  • 我估计可能是由于基于uPnP的应用程序在第一次操作之前并不“确定”设备究竟在哪。

    根据我的经验,在完成第一次uPnP操作之前是要经过一次UDP based HTTP Request广播的,uPnP组件根据从在个广播中得到的反馈来确认各种可访问设备的“位置”。

     

    可能自己实现uPnP的时候可以根据情况省略掉某些步骤吧……

    另外我猜测这类组件的用法应该是在程序启动时进行初始化,然后直到程序关闭前都不要释放的。


    Most questions i'm interested in might have two or more possible answers i know or i don't know. So please read question carefully before you try to answer, and explan your question detailedly before asking for help. 很多看起来简单的问题都存在多种可能性,如果您不能详细的解释,别人就不能正确判断出您所遭遇的实际状况,因而不能给出最适合的解决办法。在您没有给出详细信息的情况下,施助者只有张贴大量有可能有关的解决办法。而您可能没有耐心阅读所有这些东西,在这种情况下您就客观地形成了对施助者的伤害——除非“施助者”并没有用心去尝试帮助您。 同样地,当您尝试解答一个看起来“好像遇到过”的问题的时候,您也需要详细地阅读和理解这个问题。如果您不了解问题的细节,您可能会给出不相关的或者无助于解决当前问题的解答。
    2010年8月1日 18:26