tinyws--a simple Web server written in C + + (i)

Source: Internet
Author: User
Tags html interpreter

Write in front

Every yard may occasionally have its own idea of making a common software, such as operating systems, compilers, mail servers/clients, text editors, and so on. This is a bit difficult, such as operating system, do a most simple also have to pay a great effort, but most of the commonly used tools are easy to make a simple version (of course, can only play it). So I made a very humble Web server--tinyws. The main thing here is to record some of the ideas in the process.

Tinyws is done "from scratch" in C + +, which means that third-party libraries are not used in addition to the standard libraries and operating system calls of C/s. I don't like C + + (even some hate its complicated grammar rules), because, as ever, although it is my working language, but I also learn very rough. This use of it is mainly for oneself can learn it, after all took the company's money, Hee.

If you use other "advanced" languages such as Python, it will be faster to implement, in fact almost all web frameworks will bring one (of course, much more powerful than TINYWS). But if you use these languages, I'm afraid it's hard to really "start from scratch".

Currently, the code is already hosted on the https://git.oschina.net/augustus/TinyWS.git

You can clone it down with Git. Since I may occasionally make changes, there is no guarantee that the code on the GIT library will be exactly the same as in the blog (it is not really possible to post all the code here). In addition, TINYWS is written on Linux (Ubuntu 14.10 + Eclipse Luna,eclipse Project I also push to the Git library), so it may not compile properly on Windows ( The main part of the system call may be different).

Principle

The principle of the web is very simple, we all understand, I will simply write a few words, or the direct sticker code may be more abrupt.

The web is actually a client/server program that basically uses protocols such as HTTP/HTTPS/FTP to communicate. Protocol is just a way of data transmission, and for the content of the transmission, the web is basically HTML documents, of course, can also pass any other files, but as a toy, TINYWS only support the HTTP protocol.

The Web client is the browser, essentially an HTML interpreter, and all we have to do is provide a server that allows the browser to access the HTML document. A browser is a URI to access server-side resources, such as a index.html document stored on the server, on the browser side, you can use the http://serverip:port/index.html way to retrieve the document and parse it. The problem that we have to solve is that the browser gives the correct response after the request is made.

We know that network communication between hosts actually ends up passing data through a socket. The essence of the socket is that the operating system kernel implements a mapping that allows the user program to use the network as if it were a local file. Even when a port is opened with a socket, a file descriptor is returned, and all operations are identical to reading and writing to a local file. Knowing this, we've actually solved half of the problem.

The other half of the problem is how we implement the HTTP protocol. Fortunately, HTTP is a relatively simple protocol, its core is a "request and answer" process, "request" is called "method" operation procedure, in effect, is to tell the server, to request the server to return a resource (URI) or to do some operations on the resource. The usual method is get and post, currently tinyws only implement the Get method, the other methods may also be done later.

For sockets and HTTP, there are a lot of topics to check out, here is not wordy.

Requestmanager

The TINYWS core business is actually receiving HTTP requests and giving correct answers, so let's start with the top-level business. After the TINYWS runs, the socket is opened and a port is listened to, and then the Requestmanager run method runs, waiting for the HTTP request to arrive. After the request arrives, it parses the content, parses the client's request method and URI, and gives the relevant "method" to handle it.

// RequestManager.h class requestmanager{public:    requestmanager (int  connfd);     void run (); Private :    Request* getrequesthandle (); Private :     int FileDescriptor;    Request* request;};

Where Request is the base class for a specific method, its subclasses can be get,post and so on.

//RequestManager.cppnamespace{classparser{ Public: Parser (intCONNFD)    {parserequestheaders (CONNFD); }    ConstSTD::stringGetmethodname () {returnmethod; }    ConstSTD::stringGetURI () {returnURI; }Private:    voidParserequestheaders (intFD)        {Ioreader reader (FD); Std::vector<STD::string>header;        Reader.getlinesplitedbyblank (header); Method= header[0]; URI= header[1]; Version= header[2]; }Private: std::stringmethod; STD::stringURI; STD::stringversion;};} Requestmanager::requestmanager (intCONNFD): FileDescriptor (CONNFD), request (0){}voidRequestmanager::run () {if(Getrequesthandle ()) Request-execute ();} Request*Requestmanager::getrequesthandle () {Parser Parser (filedescriptor); returnRequest =Requestcreater::getrequesthandler (Parser.getmethodname (), FileDescriptor, Parser.geturi ());}

In the CPP file, we first parse the client's request data and analyze the Method,uri,version (protocol version, which is not actually used here). This work is done by the Parser class, which is used only in this place, and is sealed in the anonymous namespace. Parsing uses the Ioreader class, which is responsible for reading data from the socket, encapsulating the underlying IO operations, which is later.

Back to the chase. Requestmanager Implementation, in fact, using a factory class ( Requestcreater), based on the analytic method, to create different instances of the methods, although only support get, but still use the factory, Considering that there will be other methods such as post, it should not be overly design, hee.

// Request. h
Classrequest{ Public: voidInitintFD, std::stringURI); voidexecute (); Virtual~Request () {}protected: intGetfiledescriptor ()Const; ConstSTD::string& GetURI ()Const;Private: Virtual voidDoexecute () =0;Private: intFileDescriptor; STD::stringURI;};

Request is an abstract class, and each subclass needs to implement the Doexecute method to instantiate it. A simple "template method" is also used, which allows the entire inheritance system to be integrated into the external interface.

//Request.cppvoidRequest::init (intFD, std::stringURI) {      This->filedescriptor =FD;  This->uri =URI;}voidRequest::execute () {Doexecute ();}intRequest::getfiledescriptor ()Const{    returnFileDescriptor;}ConstSTD::string& Request::geturi ()Const{    returnURI;}

The real work is the subclass getrequest of request. But it's not too early, let's get here today, next time.

tinyws--a simple Web server written in C + + (i)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.