使用 f# 从 TcpClient 获取 Ip

Woj*_*icz 1 f#

嗨,我有一个问题。

我有一个简单的服务器,看起来像:

let private Listener ip port =
    async {

    let listener = new TcpListener(ip, port)
    listener.Start()   

    _logger.Info(printfn "Server binded to IP: %A - Port: %i" ip port)

    while listener.Pending() = false do

        try
            let! client = listener.AcceptTcpClientAsync() |> Async.AwaitTask
            clientConnectionPool.Add(client) |> ignore 
            _logger.Info(printfn "Client connected: %O" client.Client.RemoteEndPoint)
        with
            | :? ServerListenerException as ex -> _logger.Error(printfn "Exception while starting server listener - %s" ex.Message); ()

    }  
Run Code Online (Sandbox Code Playgroud)

它工作正常,问题是现在我想获取客户端 Ip 地址,通常在 c# 中我会使用:

((IPEndPoint)entry.Client.RemoteEndPoint).Address
Run Code Online (Sandbox Code Playgroud)

我相信 F# 翻译成:

let clientIp : IPAddress = (client.Client.RemoteEndPoint :> IPEndPoint).Address
Run Code Online (Sandbox Code Playgroud)

但问题是我收到消息

类型约束不匹配。“EndPoint”类型与“IPEndPoint”类型不兼容

可能是什么问题??

Fyo*_*kin 5

在 F# 中向上转换和向下转换是两件不同的事情。这是有道理的:upcast 永远不会失败,永远不会导致 a null,永远不会抛出异常。向下转型可能会失败。如果该RemoteEndPoint值不是 的实例IPEndPoint怎么办?

因此,upcast 和 downcast 由两个不同的运算符表示。你正在使用的那个 - :>- 是向上的。仅当目标类型是源类型的超类型时才有效。在你的情况下它不是 - 这就是错误告诉你的。

向下转换运算符是:?>。尝试这个:

let clientIp : IPAddress = (client.Client.RemoteEndPoint :?> IPEndPoint).Address
Run Code Online (Sandbox Code Playgroud)