gpt4 book ai didi

f# - 这个 f# echo 服务器出了什么问题?

转载 作者:行者123 更新时间:2023-12-01 23:29:53 24 4
gpt4 key购买 nike

我写了这个 f# echo 服务器:

open System.Net
open System.Net.Sockets
open System.IO
open System
open System.Text
open System.Collections.Generic

let addr = IPAddress.Parse("127.0.0.1")
let listener = new TcpListener(addr, 2000)
listener.Start()

let rec loop2(c:TcpClient,sr:StreamReader,sw:StreamWriter)=async {
let line=sr.ReadLine()
if not(line=null) then
match line with
|"quit"->
sr.Close()
sw.Close()
c.Close()
|_ ->
if line.Equals("left") then
sw.WriteLine("right")
return! loop2(c,sr,sw)
sw.WriteLine(line)
return! loop2(c,sr,sw)

else
sr.Close()
sw.Close()
c.Close()
}

let loop()=async {
while true do
let c=listener.AcceptTcpClient()
let d = c.GetStream()
let sr = new StreamReader(d)
let sw = new StreamWriter(d)
sw.AutoFlush<-true
Async.Start(loop2(c,sr,sw))
}

Async.RunSynchronously(loop())

这个程序可以做:

  1. 回应客户的信息
  2. 当客户说“左”时,返回“右”
  3. 当客户端说“退出”时,关闭连接

但是当我运行程序时,当客户端发送“左”、“右”并发送“退出”时,我得到了这个异常:

not handled exception: System.ObjectDisposedException: (con't write to closed) TextWriter。 in Microsoft.FSharp.Control.CancellationTokenOps.Start@1192-1.Invoke(Exception e) in .$Control.loop@419-40(Trampoline this, FSharpFunc2 action) in
Microsoft.FSharp.Control.Trampoline.ExecuteAction(FSharpFunc
2 firstAction) in Microsoft.FSharp.Control.TrampolineHolder.Protect(FSharpFunc`2 firstAction) in .$Control.-ctor@476-1.Invoke(Object state) in System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state) in System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, BooleanpreserveSyncCtx) in System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) in System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() in System.Threading.ThreadPoolWorkQueue.Dispatch() in System.Threading._ThreadPoolWaitCallback.PerformWaitCallback() . . .(press any key to continue)

Screenshot of program in action
Screenshot of exception

我该如何解决这个问题?

最佳答案

问题在于,与您在命令式语言中对其同名的期望不同,计算表达式中的 return 不会短路。因此,一旦 if line.Equals("right") 中的 return! 返回,即。套接字关闭后,if block 之后的代码将运行并尝试写入已关闭的套接字。解决方法是将这两行放在 else 中:

                if line.Equals("left") then
sw.WriteLine("right")
return! loop2(c,sr,sw)
else
sw.WriteLine(line)
return! loop2(c,sr,sw)

作为一个额外的样式提示,整个主体可以作为一个匹配来实现:

let rec loop2(c:TcpClient,sr:StreamReader,sw:StreamWriter)=async {
let line=sr.ReadLine()
match line with
| null | "quit" ->
sr.Close()
sw.Close()
c.Close()
| "left" ->
sw.WriteLine("right")
return! loop2(c,sr,sw)
| _ ->
sw.WriteLine(line)
return! loop2(c,sr,sw)
}

关于f# - 这个 f# echo 服务器出了什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40986137/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com