简体   繁体   中英

Web server: reading http request from stream

Greetings!

I've been fooling around with C# (again) and now i've stucked with simple HTTP web server implementation. Honestly, i don't want to get along with HTTP specification - i just need to write a very tiny (read as simple ) HTTP web server. And i've encouraged this problem: client sends request to the server and then server parses it, runs some actions, builds response and sends it back to client. That seems to be obvious (for me at least).

Here's what i've got so far:

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();
        }
    }
}

But i've met an "underwater stone": i'm reading request via input stream, so input data flow will be terminated when client close page in his browser (let's talk about the most obvious actions, excluding curl, w3 and other "geek-stuff").

So, the question is: how to determine request' end? Eg when should i stop reading request data and start sending response?

Why not use HttpListener? You can have a simple HTTP server in 5 lines of code.

This Wikipedia article explains pretty succinctly about the request message format.

The request line and headers must all end with <CR><LF> (that is, a carriage return followed by a line feed). The empty line must consist of only <CR><LF> and no other whitespace. In the HTTP/1.1 protocol, all headers except Host are optional.

Basically, watch for a blank line after the headers and/or a potential message body.

According to the HTTP specification , you can use certain headers to determine if there is a message body:

The presence of a message-body in a request is signaled by the inclusion of a Content-Length or Transfer-Encoding header field in the request's message-headers.

另一个选择是: http : //webserver.codeplex.com/即使您不想使用它,也可以窃取想法,因为它实现了完整的请求生命周期。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM