SoFunction
Updated on 2024-11-12

Python implementation of a simple HttpServer server example

To write a simple tomcat-like server, you first need to figure out these points:

1. Roles and functions of the Client and the Server

Role A requests data from role B. A can be regarded as the client and B as the server. The main responsibility of the client is to send the request and receive the request information returned by the server according to the request sent by itself, while the main responsibility of the server is to receive the request and return the request data.

2. What a browser is and how it works

We often say B/S, C/S architecture, the so-called B/S refers to browser/server, C/S refers to Client/Server, B/S architecture is actually applied to the browser program, as long as the last in the browser to show the B/S architecture, not in the browser to show the C/S architecture, such as the common League of Legends game. But the essence of only C/S architecture, because the browser is a special client.

What makes browsers special is that there are three main engines underneath:

  • DOM parsing engine: i.e. the browser can parse HTML
  • Style parsing engine: i.e. browsers can parse CSS
  • Script parsing engine: i.e. the browser can parse JAVASCRIPT.

3. Socket

The above mentioned client-server, how to realize the connection between them and data transfer, which is Socket, every programming language has Socket programming, the role of the Socket is to provide the ability to network communications

4. HTTP protocol and the difference between HTTP and TCP/TP

Clients and servers realize the ability to communicate over the network through sockets, which enables the transfer of data. The protocol is to standardize data transmission, that is to say, between the client and the server to transmit data in accordance with certain norms and standards, not blind transmission.

TCP/IP (Transmission Control Protocol/Internet Protocol): Transmission Control Protocol/Internet Protocol

HTTP (HyperText Transfer Protocol): HyperText Transfer Protocol.

TCP/TP Differences.

To make an analogy, TCP/TP is the road and HTTP is the car on the road, so HTTP must be on top of TCP/TP.

HTTP is mainly used in the web program, designed at the beginning is to provide a way to publish and receive HTML pages, so that may be very abstract and difficult to understand. Specifically when we go to visit a website, we only need to get the content based on this site (such as html, css, JavaScript). But we grab the browser to receive the resource package (you can use the Fiddler tool) found that in addition to the web page needs to be the entity content and some of the following information:

HTTP/1.1 200 OK
 Cache-Control: private
 Content-Type: text/plain; charset=utf-8
 Content-Encoding: gzip
 Vary: Accept-Encoding
 Server: Microsoft-IIS/7.5
 X-AspNet-Version: 4.0.30319
 X-Powered-By:
 Date: Tue, 24 Jan 2017 03:25:23 GMT
 Connection: close
 Content-Length: 661

This is the http protocol specification, such as Content-Type is to say that the transmission of the file format, Content-Encoding specifies the encoding format. Not only the above, very much, about the meaning of these parameters here do not go one by one introduction!

5. Meaning of URLs

URL (Uniform Resource Locator), that is, we often say that the URL, directly to the resolution of a URL to illustrate him: http://198.2.17.25:8080/webapp/

What this means is to find a server with IP 198.2.17.25 in the directory webapp

But we often see URLs like this:/archive/2005/12/10/

In fact, this is the same as the above, but here there is a domain name resolution, can be resolved to the corresponding IP address

After figuring out the above five points, start writing the code

import socket
import sys
import getFileContent
# Declare an IP and port to be bound, here the local address is used
server_address = ('localhost', 8080)
class WebServer():
  def run(self):
    print >>, 'starting up on %s port %s' % server_address
    # Instantiate a socket
    sock=(socket.AF_INET,socket.SOCK_STREAM)
    #Bind IPs and ports
    (server_address)
    #Setup Listening
    (1)
    # Here first give a dead loop, in fact, here is the need for multi-threading, and then the subsequent version will be implemented
    while True:
      # Accept the client's request and get the request information and the requested port information
      connection, client_address = ()
      print >>, 'waiting for a connection'
      try:
        # Get request information
        data = (1024)
        if data:
          # Send request messages
          ((data))
      finally:
        ()

if __name__ == '__main__':
  server=WebServer()
  ()

Very clear and concise.()The server returns information to the browser, but the data sent must follow the HTTP protocol specification
It is the HTTP protocol specification that is processed for the sent data.

import sys
import os

# Get information about the data to be sent
def getHtmlFile(data):
  msgSendtoClient=""
  requestType=data[0:("/")].rstrip()
  # Determine if it's a GET request or a POST request
  if requestType=="GET":
    msgSendtoClient=responseGetRequest(data,msgSendtoClient)
  if requestType=="POST":
    msgSendtoClient=responsePostRequest(data,msgSendtoClient)
  return msgSendtoClient

# Open the file, here do not write directly, the second is to go to fetch the file to be sent to write again
def getFile(msgSendtoClient,file):
    for line in file:
     msgSendtoClient+=line
    return msgSendtoClient

# A way to filter out requests
def getMidStr(data,startStr,endStr):
  startIndex = (startStr)
  if startIndex>=0:
    startIndex += len(startStr)
    endIndex = (endStr)
    return data[startIndex:endIndex]

# Get the size of the data to be sent, according to the HTTP protocol specification, to specify in advance the size of the content of the entity to be sent
def getFileSize(fileobject):
  (0,2)
  size = ()
  return size

# Setting up encoding formats and file types
def setParaAndContext(msgSendtoClient,type,file,openFileType):
  msgSendtoClient+="Content-Type: "+type+";charset=utf-8"
  msgSendtoClient+="Content-Length: "+str(getFileSize(open(file,"r")))+"\n"+"\n"
  htmlFile=open(file,openFileType)
  msgSendtoClient=getFile(msgSendtoClient,htmlFile)
  return msgSendtoClient

# Return data from GET requests
def responseGetRequest(data,msgSendtoClient):
  return responseRequest(getMidStr(data,'GET /','HTTP/1.1'),msgSendtoClient)

Return data from #POST requests
def responsePostRequest(data,msgSendtoClient):
  return responseRequest(getMidStr(data,'POST /','HTTP/1.1'),msgSendtoClient)

# Request return data
def responseRequest(getRequestPath,msgSendtoClient):
  headFile=open("","r")
  msgSendtoClient=getFile(msgSendtoClient,headFile)
  if getRequestPath==" ":
    msgSendtoClient=setParaAndContext(msgSendtoClient,"text/html","","r")
  else:
    rootPath=getRequestPath
    if (rootPath) and (rootPath):
      if ".html" in rootPath:
        msgSendtoClient=setParaAndContext(msgSendtoClient,"text/html",rootPath,"r")
      if ".css" in rootPath:
        msgSendtoClient=setParaAndContext(msgSendtoClient,"text/css",rootPath,"r")
      if ".js" in rootPath:
        msgSendtoClient=setParaAndContext(msgSendtoClient,"application/x-javascript",rootPath,"r")
      if ".gif" in rootPath:
        msgSendtoClient=setParaAndContext(msgSendtoClient,"image/gif",rootPath,"rb")
      if ".doc" in rootPath:
        msgSendtoClient=setParaAndContext(msgSendtoClient,"application/msword",rootPath,"rb")
      if ".mp4" in rootPath:
        msgSendtoClient=setParaAndContext(msgSendtoClient,"video/mpeg4",rootPath,"rb")
    else:
      msgSendtoClient=setParaAndContext(msgSendtoClient,"application/x-javascript","","r")
  return msgSendtoClient

Github source download./Jiashengp/Python_httpServer

This is the whole content of this article.