我正在尝试在F#中创建一个简单的HTTP服务器。但不幸的是我陷入了响应阶段,我正在尝试创建一个简单的404响应但我的浏览器不会得到它,它只会加载并加载页面永远不会去任何地方。我无法弄清楚我的代码在哪里出错。
let responseString = "HTTP/1.1 404 NOT FOUND";
let buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
let processRequest (client: TcpClient) =
async { do printfn "Incoming HTTP request..."
use stream = client.GetStream()
use sr = new StreamReader(stream)
let! content = sr.ReadToEndAsync() |> Async.AwaitTask
do
printfn "Stream contains:\n%s" content
stream.Write(buffer, 0, buffer.Length)
stream.Flush() }
let ip = IPAddress.Parse("127.0.0.1")
let listener = TcpListener(ip, 8080)
let startServer =
async { do listener.Start()
do printfn "Starting server..."
while true do
let! context = listener.AcceptTcpClientAsync() |> Async.AwaitTask
do! processRequest context }
Async.Start startServer
答案 0 :(得分:1)
问题是,TCP流不知道客户端何时发送了所有数据(除非您关闭浏览器),因此StreamReader永远被阻止。 如果你想自己实现HTTP,你需要(对于初学者)逐行阅读并检查是否允许客户端发送更多数据。
答案 1 :(得分:1)
正如@CaringDev所指出的,ReadToEnd不会终止。这说明对于一个简单的HTTP服务器,您只需要读取请求的第一行。这是代码的更新版本,只读取第一行并以200 OK响应:
open System.Net
let processRequest (client: Sockets.TcpClient) = async {
printfn "Incoming HTTP request..."
use stream = client.GetStream()
use sr = new System.IO.StreamReader(stream)
let line = sr.ReadLine()
printfn "Request: %s" line
let sw = new System.IO.StreamWriter(stream)
sw.WriteLine("HTTP/1.1 200 OK\r\n\r\nHello World")
sw.Flush()
}
let ip = IPAddress.Parse("127.0.0.1")
let listener = Sockets.TcpListener(ip, 8080)
let startServer = async {
do listener.Start()
do printfn "Starting server..."
while true do
let! context = listener.AcceptTcpClientAsync() |> Async.AwaitTask
processRequest context |> Async.Start
}
Async.Start startServer
我也很想将do! processRequest context
更改为processRequest context |> Async.Start
,以便您可以同时处理多个请求。