问题描述
我正在尝试设置服务器/客户端,此刻,我只是在做一个回显服务器,以确保到侦听器和客户端的连接正常。
但是当我尝试从一个简单的客户端向我的服务器发送数据时,我遇到了一个问题。在强制关闭终端中的客户端后,它没有发送或发送。
我以前用C编写过服务器/客户端应用程序,但现在正在尝试使用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中。
解决方法
我在评论中看到您找到了主要问题(缺少文件结尾字符)。但是,我认为服务器代码中有一个潜在的问题值得解决(即使现在并没有引起任何麻烦)。
潜在的问题是,您使用client
绑定了use
值,然后在后台启动的异步块中使用了它。
while true do
use client = connlst.AcceptTcpClient()
async {
// #1 use 'client' here
} |> Async.Start
// #2 do some more work here
如果循环(#2)的迭代在异步块(#1)完成之前完成,则它将处理客户端,而客户端可能仍在异步块中使用它。避免此问题的简单技巧是在use
内使用async
:
while true do
let client = connlst.AcceptTcpClient()
async {
use client = client
// #1 use 'client' here
} |> Async.Start
// #2 do some more work here