F#TcpListener/Clientclass不写?
F# TcpListener/Client class do not write?
我正在尝试设置 server/client,目前我只是在做一个回声服务器,以确保与侦听器和客户端的连接正常。
但是我遇到了一个问题,当我试图从一个简单的客户端向我的服务器发送数据时,它没有被发送,或者在我强制关闭终端中的客户端后它被发送了。
我以前用 C 编写过 server/client 应用程序,但我现在正在尝试使用 F#。
客户代码:
let Client (ip :IPAddress, port) =
use client = new TcpClient(ip.ToString(), port)
use reader = new StreamReader (client.GetStream())
use writer = new StreamWriter (client.GetStream())
writer.AutoFlush <- true
let mutable run = true
while run do
let input = Console.ReadLine()
if input = "Exit"
then run <- false
else
writer.Write input
reader.ReadToEnd()
|> printfn "got : %s"
服务器代码:
let Server (ip : IPAddress, port) =
let connlst = TcpListener(ip, port)
connlst.Start()
let mutable run = true
while run do
use client = connlst.AcceptTcpClient()
async {
use reader = new StreamReader (client.GetStream())
use writer = new StreamWriter (client.GetStream())
writer.AutoFlush <- true
printfn "Got : %s" (reader.ReadToEnd())
writer.WriteLine "hello"
}
|> Async.Start
if Console.ReadLine() = "Exit"
then run <- false
else ()
这是两个应用程序的主要功能中的功能 运行。如果我在终端启动服务器并在我的浏览器中输入 ip:port 它连接正常给我 http 请求和所有。但发回部分不发送。 (writer.write)
如果我正在连接我的客户端,它会连接但不会发送消息,直到我强制客户端关闭,我已经尝试不将流包装到没有帮助的 StreamWriter 中。
我在评论中看到您发现了主要问题(缺少 end-of-file 字符)。但是,我认为服务器代码中存在一个值得解决的潜在问题(即使它现在没有造成任何问题)。
潜在的问题是您使用 use
绑定 client
值,但随后在后台启动的异步块中使用它。
while true do
use client = connlst.AcceptTcpClient()
async {
// #1 use 'client' here
} |> Async.Start
// #2 do some more work here
如果循环迭代 (#2) 在异步块 (#1) 完成之前完成,那么它会在客户端可能仍在异步块中使用时处理它。避免此问题的一个简单技巧是在 async
:
中使用 use
while true do
let client = connlst.AcceptTcpClient()
async {
use client = client
// #1 use 'client' here
} |> Async.Start
// #2 do some more work here
我正在尝试设置 server/client,目前我只是在做一个回声服务器,以确保与侦听器和客户端的连接正常。
但是我遇到了一个问题,当我试图从一个简单的客户端向我的服务器发送数据时,它没有被发送,或者在我强制关闭终端中的客户端后它被发送了。
我以前用 C 编写过 server/client 应用程序,但我现在正在尝试使用 F#。
客户代码:
let Client (ip :IPAddress, port) =
use client = new TcpClient(ip.ToString(), port)
use reader = new StreamReader (client.GetStream())
use writer = new StreamWriter (client.GetStream())
writer.AutoFlush <- true
let mutable run = true
while run do
let input = Console.ReadLine()
if input = "Exit"
then run <- false
else
writer.Write input
reader.ReadToEnd()
|> printfn "got : %s"
服务器代码:
let Server (ip : IPAddress, port) =
let connlst = TcpListener(ip, port)
connlst.Start()
let mutable run = true
while run do
use client = connlst.AcceptTcpClient()
async {
use reader = new StreamReader (client.GetStream())
use writer = new StreamWriter (client.GetStream())
writer.AutoFlush <- true
printfn "Got : %s" (reader.ReadToEnd())
writer.WriteLine "hello"
}
|> Async.Start
if Console.ReadLine() = "Exit"
then run <- false
else ()
这是两个应用程序的主要功能中的功能 运行。如果我在终端启动服务器并在我的浏览器中输入 ip:port 它连接正常给我 http 请求和所有。但发回部分不发送。 (writer.write)
如果我正在连接我的客户端,它会连接但不会发送消息,直到我强制客户端关闭,我已经尝试不将流包装到没有帮助的 StreamWriter 中。
我在评论中看到您发现了主要问题(缺少 end-of-file 字符)。但是,我认为服务器代码中存在一个值得解决的潜在问题(即使它现在没有造成任何问题)。
潜在的问题是您使用 use
绑定 client
值,但随后在后台启动的异步块中使用它。
while true do
use client = connlst.AcceptTcpClient()
async {
// #1 use 'client' here
} |> Async.Start
// #2 do some more work here
如果循环迭代 (#2) 在异步块 (#1) 完成之前完成,那么它会在客户端可能仍在异步块中使用时处理它。避免此问题的一个简单技巧是在 async
:
use
while true do
let client = connlst.AcceptTcpClient()
async {
use client = client
// #1 use 'client' here
} |> Async.Start
// #2 do some more work here