.net - Tcplistener 随机重置连接

标签 .net f# network-programming tcplistener

我正在玩一个用 F# 编写的简单网络服务器。正如我所注意到的,如果我在 Firefox 中点击刷新,经过一些尝试,我会收到一个错误页面:

The connection was reset

The connection to the server was reset while the page was loading.

为什么这似乎是随机发生的(将积压工作增加到 1000 没有帮助)?另外,为什么 Firefox 是唯一显示我的网络服务器响应的浏览器?我想我的回复无效,对吗?

网络服务器的代码:

module Program

open System
open System.Net.Sockets
open System.IO

type TcpListener with
   member this.AsyncAcceptSocket =
    Async.FromBeginEnd(this.BeginAcceptSocket, this.EndAcceptSocket)

type Main =
    static member Init () =
        let tcpListener = new TcpListener(80)        
        tcpListener.Start()

        let rec loop =
            async{                                
                let! socket = tcpListener.AsyncAcceptSocket
                Async.Start(loop)
                let stream = new NetworkStream(socket)
                let streamWriter = new StreamWriter(stream)                
                
                streamWriter.WriteLine("HTTP/1.0 200 OK");
                streamWriter.WriteLine("Date: Fri, 15 Nov 2011 23:59:59 GMT");
                streamWriter.WriteLine("Content-Type: text/html");
                streamWriter.WriteLine("Content-Length: 13540");
                streamWriter.WriteLine("")
                streamWriter.WriteLine("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">");
                streamWriter.WriteLine("<html>");
                streamWriter.WriteLine("<body>");
                streamWriter.WriteLine("<h1>This is the title</h1>");
                streamWriter.WriteLine("</body>");
                streamWriter.Write("</html>");                
                streamWriter.Flush()                        
                stream.Close()
                socket.Close()
            }

        Async.Start(loop)

        Console.ReadLine()

Main.Init()

编辑

问题似乎与我在之前的解决方案中调用 loop 的方式无关。我已将程序缩减为这样(但我的问题仍然存在):

module Program

open System
open System.Net.Sockets
open System.IO

let tcpListener = new TcpListener(80)        
tcpListener.Start()

while true do                            
    let socket = tcpListener.AcceptSocket()
    let stream = new NetworkStream(socket)
    let streamWriter = new StreamWriter(stream)                
                
    streamWriter.WriteLine("response");             
    streamWriter.Flush()                        
    stream.Close()
    socket.Close()

Console.ReadLine()

最佳答案

这是一个工作版本。我会使用 TcpClient 而不是套接字,这样您就不必管理其下划线流。

module Program

open System
open System.Net
open System.Net.Sockets
open System.IO

type TcpListener with
   member this.AsyncAcceptTcpClient() =
    Async.FromBeginEnd(this.BeginAcceptTcpClient, this.EndAcceptTcpClient)

type Main =
    static member Init() =
        let tcpListener = new TcpListener(IPAddress.Loopback, 80)
        tcpListener.Start()

        let writeContent() =
            let stream = new MemoryStream()
            let streamWriter = new StreamWriter(stream)
            streamWriter.WriteLine("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">")
            streamWriter.WriteLine("<html>")
            streamWriter.WriteLine("<body>")
            streamWriter.WriteLine("<h1>This is the title</h1>")
            streamWriter.WriteLine("</body>")
            streamWriter.Write("</html>")
            streamWriter.Flush()
            stream

        let rec loop() =
            async {
                use! tcp = tcpListener.AsyncAcceptTcpClient()
                let stream = tcp.GetStream()
                use streamWriter = new StreamWriter(stream)
                use content = writeContent()

                streamWriter.WriteLine("HTTP/1.0 200 OK")
                streamWriter.WriteLine("Date: Fri, 15 Nov 2011 23:59:59 GMT")
                streamWriter.WriteLine("Content-Type: text/html")
                streamWriter.WriteLine("Content-Length: {0}", content.Length)
                streamWriter.WriteLine("")
                streamWriter.Flush()

                content.WriteTo stream
                stream.Flush()
                return! loop()
            }

        Async.Start(loop())

        Console.ReadLine() |> ignore

Main.Init()

关于.net - Tcplistener 随机重置连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8142891/

相关文章:

java - p2p0 是 android 中 WIFI DIRECT 的无线接口(interface)吗?

c# - SqlParameter无法与INSERT语句一起使用

c# - 我应该如何从 .NET MVC 应用程序中的所有函数返回通用响应和响应代码?

f# - 如何使用 fparsec 测试正好 2 个字符?

java - 是否有 : java. lang.RuntimeException 的解决方法:无法生成 DH key 对

java - 在 RFB 协议(protocol)中提交 (x,y) 位置

c# - 从 MethodInfo 获取程序集路径

.net - 4.5 中的 CallerMemberName 属性是 "able to be faked"吗?

f# - 如何在 F# 中定义执行顺序?

c# - 可以动态分析谓词吗?