下面是不是一個解決方案,但解決方法。它解決了主機未發現錯誤的問題,而無需使用@rmunn的答案中提到的railway-oriented programming。 (這是一個偉大的文章,順便說一句。)
所以false
可如果Dns.GetHostEntry
拋出異常或返回如果check_response
未能從HELO
正確的響應。
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
)
修復後,發生了第二個錯誤。它抱怨11001以及原來的錯誤說它應該是IPHostEntry。 – octopusgrabbus
@octopusgrabbus - 我原來的回答錯了:'SocketErrorCode'是一個枚舉。我已經更新了它。讓我看看有關IPHostEntry的事情。 – rmunn
...和'printfn'是錯誤的。 'printfn'返回'()','單元'類型。但是'try ... with'表達式的每個分支需要返回與'Dns.GetHostEntry'相同的類型,否則會拋出異常。所以我更新了我的示例以拋出異常,因爲沒有有意義的'IPHostEntry'可以返回。除非你重寫這個函數來使用[鐵路編程](http://fsharpforfunandprofit.com/posts/recipe-part2/)風格,但這是一個更大的問題。 – rmunn