How to create an HTTP server (1)
HTTP Overview
Understand the Web Server:
Compile an HTTP (Hypertext Transfer Protocol) server, that is, the Web server. We can define it as follows: Based on the HTTP protocol, transfer the corresponding webpage file to the Customer Service server. HTTP is an application layer protocol designed for Hypertext Transfer. This protocol is also based on TCP/IP.
Well, let's take a look at this example to help us understand: We usually open a webpage in a browser. First, enter the url in the address bar of the browser to confirm. This is actually sending a request for webpage data to the Web server, at this time, the Web server will transmit data to the browser according to the specified rule format, and the browser will receive the data resolution display, that is, the page we see. Here, the browser is equivalent to the client. The fixed data format is the HTTP protocol. The job of the Web server is to transmit the data to the browser.
HTTP protocol:
1. HTTP is a Stateless protocol (short link). The server immediately disconnects the connection after responding to the client request. In other words, the server does not maintain the client status. Even if the same client sends a request again, the server cannot identify the original one and process the new request in the same way. Cookie and Session technologies are usually used in Web programming to make up for the disadvantage that HTTP cannot maintain connections.
2. Web Server Message request methods: GET and POST are two request methods. The GET request data can be easily written directly to the URL address to transmit data because it does not have a message body, the data parameters to be transmitted can only be transmitted through the url address, which is also not safe. POST can be inserted into the message body. Therefore, when the client transmits data to the server, the message body can be used for transmission without having to write the url address. This is more secure and convenient for transmission of big data.
3. Structure of the HTTP request message, including the request line, message header, blank line, and message body. The request line can only be sent through one line. For example, "GET/index.html HTTP/1.1”" requests the index.html file in the getformat and requires communication with the HTTP protocol of Version 1.1. Message Headers generally include additional information such as browser information and user authentication. The message body and the message header must be separated by blank lines to prevent boundary issues. The message body contains data transmitted from the client to the server. Only the POST method has the message body. (Structure of the data packet sent by the client to the server)
4. HTTP Response Message structure: including the status line, message header, blank line, and message body. The status line contains the processing result of the client request, for example, "HTTP/1.1 200 OK". I want to use HTTP1.1 for response. Your request is processed correctly (200 OK ), there are several typical status codes: The 200 0 K table successfully processes the Request, the 404 Not Found table Request file does Not exist, and the 400 Bad Request Table Request method is incorrect. Please check. The message header contains the type and length of the transmitted data. Insert a space to the message body and send the file data to the customer service. (The data packet structure of the server responding to the client request)
Linux-based multi-thread Web Server
Here, the Web server uses the multi-thread concurrency mode, but does not use the IOCP or epoll model, because the client and the server immediately disconnect after one data exchange, there is not enough time to take advantage of IPCP or epoll. When messages of different sizes are frequently sent when the server and the client maintain a long connection (the most typical is the online gaming server), the advantages of these two models can be truly realized.
- //
-
- // Main. cpp
-
- // Hello_server
-
- //
-
- // Created by app05 on 15-10-27.
-
- // Copyright (c) 2015 app05. All rights reserved.
-
- //
-
- # Include
-
- # Include
-
- # Include
-
- # Include
-
- # Include
-
- # Include
-
- # Include
-
- # Define BUF_SIZE 1024
-
- # Define SMALL_BUF 100
-
- Void * request_handler (void * arg); // thread entry function
-
- Void send_data (FILE * fp, char * ct, char * file_name); // send data to the client of the browser
-
- Char * content_type (char * file); // data type
-
- Void send_error (FILE * fp); // send error processing data
-
- Void error_handling (char * message); // console error printing
-
- Int main (int argc, char * argv [])
-
- {
-
- Int serv_sock, clnt_sock;
-
- Struct sockaddr_in serv_adr, clnt_adr;
-
- Socklen_t clnt_adr_sz;
-
- Char buf [BUF_SIZE];
-
- Pthread_t t_id;
-
- If (argc! = 2 ){
-
- Printf ("Usage: % s \ n", argv [0]);
-
- Exit (1 );
-
- }
-
- Serv_sock = socket (PF_INET, SOCK_STREAM, 0 );
-
- Memset (& serv_adr, 0, sizeof (serv_adr ));
-
- Serv_adr.sin_family = AF_INET;
-
- Serv_adr.sin_addr.s_addr = htonl (INADDR_ANY );
-
- Serv_adr.sin_port = htons (atoi (argv [1]);
-
- If (bind (serv_sock, (struct sockaddr *) & serv_adr, sizeof (serv_adr) =-1)
-
- Error_handling ("bind () error ");
-
- If (listen (serv_sock, 5) =-1)
-
- Error_handling ("listen () error ");
-
- While (1)
-
- {
-
- Clnt_adr_sz = sizeof (clnt_adr );
-
- Clnt_sock = accept (serv_sock, (struct sockaddr *) & clnt_adr, & clnt_adr_sz );
-
- Printf ("Connection Request: % s: % d \ n", inet_ntoa (clnt_adr.sin_addr), ntohs (clnt_adr.sin_port); // The Client IP address and port used for Connection
-
- // Multithreading
-
- Pthread_create (& t_id, NULL, request_handler, (void *) & clnt_sock );
-
- Pthread_detach (t_id );
-
- }
-
- Close (serv_sock );
-
- Return 0;
-
- }
-
- // Client request message processing
-
- Void * request_handler (void * arg)
-
- {
-
- Int clnt_sock = * (int *) arg );
-
- Char req_line [SMALL_BUF];
-
- FILE * clnt_read;
-
- FILE * clnt_write;
-
- Char method [10];
-
- Char ct [15];
-
- Char file_name [30];
-
- /* Convert a socket to a standard I/O operation */
-
- Clnt_read = fdopen (clnt_sock, "r ");
-
- Clnt_write = fdopen (dup (clnt_sock), "w ");
-
- Fgets (req_line, SMALL_BUF, clnt_read); // save request row data
-
- If (strstr (req_line, "HTTP/") = NULL) // check whether it is an HTTP request
-
- {
-
- Send_error (clnt_write );
-
- Fclose (clnt_read );
-
- Fclose (clnt_write );
-
- Return NULL;
-
- }