HTTP Protocol (Request and Response under B/S Architecture)

  1. HTTP protocol
    Definition: Hypertext File Transfer Protocol (https: for encryption), which specifies the format of data to be transmitted between two parties
    Understanding: http protocol is mainly the interaction between browser and server; the bottom layer of browser is socket socket
    Verification: Send data to browser using network debugging assistant
  2. http protocol request and corresponding
  • Request: Composition (request header, blank line, request body)
    Request Header: Request Mode Request Address http Protocol (GET/index.html HTTP/1.1)
    Line break: rn
    GET request format:
    GET /path HTTP/1.1
    Header1: Value1
    Header2: Value2
    ...
    Each Header has one line and the newline character isrn

    Format of POST request:
    POST /path HTTP/1.1
    Header1: Value1
    Header2: Value2

    body date goes here...
    When two consecutive \r\n are encountered, the Header part ends, and all the data behind is body.

  • Response: Composition (response header empty response body)

    HTTP/1.1 200 OK\r\n
    \r\n
    body

  1. Use python socket to build static server to communicate with Client.
import socket
import re


def handle_client(client_socket):
    "Serving a client"
    recv_data = client_socket.recv(1024).decode('utf-8', errors="ignore")
    request_header_lines = recv_data.splitlines()
    for line in request_header_lines:
        print(line)

    http_request_line = request_header_lines[0]
    get_file_name = re.match("[^/]+(/[^ ]*)", http_request_line).group(1)
    print("file name is ===>%s" % get_file_name)  # for test

    # If you do not specify which page to visit. For example, index.html
    # GET / HTTP/1.1
    if get_file_name == "/":
        get_file_name = DOCUMENTS_ROOT + "/index.html"
    else:
        get_file_name = DOCUMENTS_ROOT + get_file_name

    print("file name is ===2>%s" % get_file_name) #for test

    try:
        f = open(get_file_name, "rb")
    except IOError:
        # 404 means no page
        response_headers = "HTTP/1.1 404 not found\r\n"
        response_headers += "\r\n"
        response_body = "====sorry ,file not found===="
    else:
        response_headers = "HTTP/1.1 200 OK\r\n"
        response_headers += "\r\n"
        response_body = f.read()
        f.close()
    finally:
        # Because header information is organized in strings and cannot be merged with data read from binary open files, it is sent separately.
        # Send the response header first
        client_socket.send(response_headers.encode('utf-8'))
        # Resend body
        client_socket.send(response_body)
        client_socket.close()


def main():
    "As the main control entry of the program"
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server_socket.bind(("", 7788))
    server_socket.listen(128)
    while True:
        client_socket, clien_cAddr = server_socket.accept()
        handle_client(client_socket)


#Configure the server here
DOCUMENTS_ROOT = "./html"

if __name__ == "__main__":
    main()


demo02  http Server multiprocess (concurrency) 
import socket
import re
import multiprocessing


class WSGIServer(object):

    def __init__(self, server_address):
        # Create a tcp socket
        self.listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # Allow immediate use of last bound port
        self.listen_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        # binding
        self.listen_socket.bind(server_address)
        # Turn passive and set the length of the queue
        self.listen_socket.listen(128)

    def serve_forever(self):
        "cycle operation web Server, Waiting for Client Link and Serving Client"
        while True:
            # Waiting for a new client to arrive
            client_socket, client_address = self.listen_socket.accept()
            print(client_address)  # for test
            new_process = multiprocessing.Process(target=self.handleRequest, args=(client_socket,))
            new_process.start()

            # Because the child process has copied the socket and other resources of the parent process, the parent process call close will not close their corresponding link.
            client_socket.close()

    def handleRequest(self, client_socket):
        "Serve a client with a new process"
        recv_data = client_socket.recv(1024).decode('utf-8')
        print(recv_data)
        requestHeaderLines = recv_data.splitlines()
        for line in requestHeaderLines:
            print(line)

        request_line = requestHeaderLines[0]
        get_file_name = re.match("[^/]+(/[^ ]*)", request_line).group(1)
        print("file name is ===>%s" % get_file_name) # for test

        if get_file_name == "/":
            get_file_name = DOCUMENTS_ROOT + "/index.html"
        else:
            get_file_name = DOCUMENTS_ROOT + get_file_name

        print("file name is ===2>%s" % get_file_name) # for test

        try:
            f = open(get_file_name, "rb")
        except IOError:
            response_header = "HTTP/1.1 404 not found\r\n"
            response_header += "\r\n"
            response_body = "====sorry ,file not found===="
        else:
            response_header = "HTTP/1.1 200 OK\r\n"
            response_header += "\r\n"
            response_body = f.read()
            f.close()
        finally:
            client_socket.send(response_header.encode('utf-8'))
            client_socket.send(response_body)
            client_socket.close()


# Setting the port of the server
SERVER_ADDR = (HOST, PORT) = "", 8888
# Setting the Path for Server Service Static Resources
DOCUMENTS_ROOT = "./html"


def main():
    httpd = WSGIServer(SERVER_ADDR)
    print("web Server: Serving HTTP on port %d ...\n" % PORT)
    httpd.serve_forever()

if __name__ == "__main__":
    main()

Tags: socket Web Server network Python

Posted on Wed, 09 Oct 2019 13:17:58 -0400 by kwdelre