首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何捕获SocketException

如何捕获SocketException
EN

Stack Overflow用户
提问于 2017-04-19 15:18:43
回答 2查看 670关注 0票数 1

我在构造以下F# try..with语句的try..with部分时遇到了问题。有很多异常处理示例,但是当主机不存在时,我找不到与从SocketException返回的Dns.GetHostEntry具体匹配的实例。我会继续寻找,但希望得到一个指针。

代码语言:javascript
复制
let test_smtp (smtp_server_address : string) (port : int) =
    let expectedResultCode = 220
    let hostEntry : IPHostEntry =  
        try 
            Dns.GetHostEntry(smtp_server_address)
        with
            | :? System.Net.Sockets.SocketException -> printfn "GetHostEntry threw an exception "

    let endPoint : IPEndPoint = new IPEndPoint (hostEntry.AddressList.[0], port)
    ( use tcpSocket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp) 
      tcpSocket.Connect(endPoint)

      let temp_result = check_response tcpSocket expectedResultCode 
      temp_result
    )
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-04-19 15:41:58

到目前为止,您所拥有的是很好的;您只需要添加as (name)语法来给异常对象命名,然后用when (test)语法来测试某个条件是否成立。例如:

代码语言:javascript
复制
try 
  Dns.GetHostEntry(smtp_server_address)
with
  | :? System.Net.Sockets.SocketException as ex when ex.SocketErrorCode = SocketError.HostNotFound ->
    failwith "Host not found"

(注意:我的原始代码通过int测试了SocketErrorCode,因为我误读了MSDN文档。但SocketErrorCode枚举值

关于您的代码的一个注释:您不需要在use tcpSocket = ...表达式周围加上那些括号。您只需将其与代码的其余部分内联编写即可,当F#在函数结束时超出作用域时,它将释放tcpSocket值:

代码语言:javascript
复制
let test_smtp (smtp_server_address : string) (port : int) =
    let expectedResultCode = 220
    let hostEntry : IPHostEntry =  
        try 
            Dns.GetHostEntry(smtp_server_address)
        with
            | :? System.Net.Sockets.SocketException as ex when ex.SocketErrorCode = SocketError.HostNotFound ->
                failwith "GetHostEntry threw an exception "

    let endPoint : IPEndPoint = new IPEndPoint (hostEntry.AddressList.[0], port)
    use tcpSocket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp) 
    tcpSocket.Connect(endPoint)

    check_response tcpSocket expectedResultCode 
票数 1
EN

Stack Overflow用户

发布于 2017-04-19 17:03:48

以下不是解决方案,而是解决办法。它不用使用@rmunn的答案中提到的面向铁路的规划就可以解决主机找不到的错误的问题。(顺便说一句,这是一篇很棒的文章。)

因此,如果false抛出异常,或者check_response无法从HELO获得正确的响应,则可以返回HELO

代码语言:javascript
复制
module net_utilF_mod

open System
open System.Text
open System.Threading
open System.Net
open System.Net.Sockets
open System.IO

type Smtp1() = 
    member this.X = "F#"

let send_data (socket : Socket) (data : string) =
    let dataArray : byte [] = Encoding.ASCII.GetBytes(data)
    socket.Send(dataArray, 0, dataArray.Length, SocketFlags.None)

let check_response (socket:Socket) expectedResultCode =
    while socket.Available = 0 do
        System.Threading.Thread.Sleep 100  

    let responseArray : byte [] = Array.zeroCreate 1024
    socket.Receive(responseArray, 0, socket.Available, SocketFlags.None) |> ignore
    let responseData : string = Encoding.ASCII.GetString(responseArray)
    let responseCode : int = Convert.ToInt32(responseData.Substring(0,3))
    if responseCode = expectedResultCode then
        true
    else
        false

let test_smtp (smtp_server_address : string) (port : int) =
    let helo_msg = String.Format("HELO {0}\r\n", Dns.GetHostName())
    let hostEntry : IPHostEntry =  
        try 
            Dns.GetHostEntry(smtp_server_address)
        with
            | :? System.Net.Sockets.SocketException as ex when ex.SocketErrorCode = SocketError.HostNotFound ->
                 let tempEntry : IPHostEntry = Dns.GetHostEntry(@"localhost")
                 tempEntry

    let email_server_reachable =
        match hostEntry.HostName with
        | @"localhost" -> false
        | _ ->  true


    if false = email_server_reachable then
        false
    else
        let endPoint : IPEndPoint = new IPEndPoint (hostEntry.AddressList.[0], port)
        ( use tcpSocket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp) 
          tcpSocket.Connect(endPoint) |> ignore

          let temp_response = 
              if true = check_response tcpSocket  220 then
                send_data tcpSocket helo_msg  |> ignore
                check_response tcpSocket 250              
              else
                false

          temp_response 
        )
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43499813

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档