4

尝试在 Clojure CLR 中执行等效的 c# 代码

using System.Net;
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
EndPoint remote = (EndPoint) sender;
recv = sock.ReceiveFrom(data, ref remote);

我在 Clojure 中尝试过的不起作用:

(let [
      sender (IPEndPoint. (IPAddress/Any) 0)
      ^EndPoint remote ^EndPoint sender
      recv (.ReceiveFrom sock data (by-ref remote))
      ]
      (println (.ToString remote))
      ;; Do something with data...
 )

它只显示 0.0.0.0:0 我认为 ref 不起作用,但也不确定提示/强制转换语法。

我在这里查看了有关参考https://github.com/richhickey/clojure-clr/wiki/CLR-Interop的信息 以及这里关于指定类型的信息:https ://github.com/clojure/clojure-clr/wiki /指定类型

4

1 回答 1

0

我翻译了问题评论中引用的 MSDN 文章。

(ns test.me
    (:import [System.Net IPHostEntry Dns IPEndPoint EndPoint IPAddress]
             [System.Net.Sockets Socket SocketType ProtocolType]))

(set! *warn-on-reflection* true)

(defn f []
   (let [hostEntry (Dns/GetHostEntry (Dns/GetHostName))
         endPoint (IPEndPoint. ^IPAddress (first (.AddressList hostEntry)) 11000)
         sender (IPEndPoint. (IPAddress/IPv6Any) 0)
         msg (byte-array 256)]       
     (with-open [s (Socket. (.AddressFamily (.Address endPoint))
                            SocketType/Dgram
                            ProtocolType/Udp)]
       (.Bind s endPoint)
       (.ReceiveFrom s  msg (by-ref sender))
       (println sender))))

运行它会产生:

>Clojure.Main.exe
Clojure 1.7.0-master-SNAPSHOT
user=> (load "/test/me")
nil
user=> (in-ns 'test.me)
#object[Namespace 0xaca85c "test.me"]
test.me=> (f)
#object[IPEndPoint 0x2126697 [fefe::3030:cfdf:f7f7:ecec%11]:55056]
nil

(IP地址已编辑)

您可能需要IPAddress/IPv6Any针对您的系统进行调整。

with-open表单用于在退出时自动关闭套接字。

请注意,只需要很少的类型提示(实际上是一个)。我已打开反射警告——这是确定您是否需要更多提示的最佳方式。(在这种情况下,如果没有^IPAddress类型提示,加载会失败并出现错误,因为它无法解析IPEndPoint构造函数。)

于 2015-05-23T14:30:29.007 回答