F#尝试将HTTP响应写入TCP流

时间:2015-03-20 16:01:46

标签: http tcp f#

我正在尝试在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

2 个答案:

答案 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,以便您可以同时处理多个请求。