C# Web服务器:从流中读取http请求

C# Web服务器:从流中读取http请求,c#,.net,http,C#,.net,Http,你好 我一直在玩弄C#(又一次),现在我又在玩弄简单的HTTP web服务器实现。老实说,我不想接受HTTP规范——我只需要编写一个非常小(读起来很简单)的HTTP web服务器。我鼓励这个问题:客户机向服务器发送请求,然后服务器解析它,运行一些操作,生成响应并将其发送回客户机。这似乎是显而易见的(至少对我来说) 以下是到目前为止我得到的信息: using System; using System.Collections.Generic; using System.Linq; using Sys

你好

我一直在玩弄C#(又一次),现在我又在玩弄简单的HTTP web服务器实现。老实说,我不想接受HTTP规范——我只需要编写一个非常小(读起来很简单)的HTTP web服务器。我鼓励这个问题:客户机向服务器发送请求,然后服务器解析它,运行一些操作,生成响应并将其发送回客户机。这似乎是显而易见的(至少对我来说)

以下是到目前为止我得到的信息:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            TcpListener listener = new TcpListener(IPAddress.Any, 80);
            listener.Start();

            Socket sock = listener.AcceptSocket();

            try
            {
                Stream s = new NetworkStream(sock);
                s.ReadTimeout = 300;

                StreamReader reader = new StreamReader(s);
                StreamWriter writer = new StreamWriter(s);
                writer.AutoFlush = true;

                Console.WriteLine("Client stream read:\r\n");

                string str = "none";

                while (sock.Connected && !reader.EndOfStream && str.Length > 0) // here's where i'm stuck
                {
                    str = reader.ReadLine();
                    Console.WriteLine("{0} ({1})", str, str.Length);
                }

                Console.WriteLine("Sending response...\r\n");

                {
                    string response = "<h1>404: Page Not Found</h1>";
                    writer.WriteLine("HTTP / 1.1 404 Not Found");
                    writer.WriteLine("Content-Type: text/html; charset=utf-8");
                    writer.WriteLine("Content-Length: {0}", response.Length);
                    writer.WriteLine("\r\n{0}", response);
                }

                Console.WriteLine("Client: over\r\n");

                s.Close();
                sock.Close();
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception: {0}\r\nTrace: \r\n{1}", e.Message, e.StackTrace);
            }

            Console.ReadKey();
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
Net系统;
使用System.Net.Sockets;
使用System.IO;
命名空间控制台应用程序1
{
班级计划
{
静态void Main(字符串[]参数)
{
TcpListener侦听器=新的TcpListener(IPAddress.Any,80);
listener.Start();
Socket sock=listener.AcceptSocket();
尝试
{
流s=新网络流(sock);
s、 ReadTimeout=300;
StreamReader=新的StreamReader;
StreamWriter writer=新的StreamWriter;
writer.AutoFlush=true;
Console.WriteLine(“客户端流读取:\r\n”);
string str=“无”;
while(sock.Connected&&!reader.EndOfStream&&str.Length>0)//这里是我被卡住的地方
{
str=reader.ReadLine();
WriteLine(“{0}({1})”,str,str.Length);
}
Console.WriteLine(“发送响应…\r\n”);
{
string response=“404:找不到页面”;
writer.WriteLine(“未找到HTTP/1.1 404”);
writer.WriteLine(“内容类型:text/html;charset=utf-8”);
writer.WriteLine(“内容长度:{0}”,response.Length);
writer.WriteLine(“\r\n{0}”,响应);
}
Console.WriteLine(“客户端:结束\r\n”);
s、 Close();
sock.Close();
}
捕获(例外e)
{
WriteLine(“异常:{0}\r\n路径:\r\n{1}”,e.Message,e.StackTrace);
}
Console.ReadKey();
}
}
}
但我遇到了一个“水下石头”:我正在通过输入流读取请求,所以当客户端在其浏览器中关闭页面时,输入数据流将被终止(让我们谈谈最明显的动作,不包括curl、w3和其他“极客东西”)


所以,问题是:如何确定请求“结束”?例如,我应该何时停止读取请求数据并开始发送响应?

为什么不使用HttpListener?您可以用5行代码创建一个简单的HTTP服务器。

非常简洁地解释了请求消息格式

请求行和标题必须全部以结尾(即,回车符后跟换行符)。空行只能由空格组成,不能包含其他空格。在HTTP/1.1协议中,除主机之外的所有头都是可选的

基本上,注意标题和/或潜在消息正文后的空行

根据,您可以使用某些标头来确定是否存在消息正文:

通过在请求的消息头中包含内容长度或传输编码头字段来表示请求中存在消息体


另一个选择是:
即使你不想使用它,你也可以偷主意,因为它实现了完整的请求生命周期。

为什么不使用
HttpListener
?'因为它在某些Windows版本中不受支持在某些地方可能是个好主意,但我们并不是只关注少数平台,不是吗?=)你是想说你需要支持WindowsXPSP2之前的平台吗?如果你真的想要跨平台,那么Kayak服务器可能是一个不错的选择。隐马尔可夫模型。。。是的,我正在搜索“\r\n”。但我如何处理消息体?