python 기반 간단 한 웹 서버 구현

웹 개발 을 하 는 당신 은 정말 웹 서버 처리 체 제 를 잘 알 고 있 습 니까?
 
분석 요청 데이터
 
다음은 원본 요청 데이터 입 니 다.
b'GET / HTTP/1.1\rHost: 127.0.0.1:8000\rConnection: keep-alive\rCache-Control: max-age=0\rUpgrade-Insecure-Requests: 1\rUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36\rAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8\rAccept-Encoding: gzip, deflate, br\rAccept-Language: zh-CN,zh;q=0.8\rCookie: csrftoken=gnaOXtlMlCxgjq62jUzBjv6XedPpVvxotWq2R6KpTv9dK2eHCwXlApyNEl9anzp9\r\r'
어디서 많이 본 듯 한 느낌 이 들 지 않 습 니까? 맞습니다. chrome 개발 자 도 구 를 열 고 웹 페이지 를 마음대로 열 면 위 와 같은 정 보 를 볼 수 있 습 니 다. 서버 에 보 내 는 것 은 위의 형식 입 니 다. 이미 \ r 분할 처리 되 었 습 니 다.
  • 상기 내용 을 분석 한 결과 각 항목 간 에 \ r 분할
  • 마지막 에 2 개의 \ r 로 끝 납 니 다. 즉, 우리 가 클 라 이언 트 에 응답 할 때 내용 과 응답 헤드 중간 에 2 개의 \ r 로 분할 합 니 다
  • 간단 한 웹 서버 구현
     
    1. 정적 자원
    주요 사고방식 은 다음 과 같다.
  • socket 서비스 감청 클 라 이언 트 연결 열기
  • 다 중 프로 세 스 방식 으로 동시 연결 처리
  • 메시지 분석 규칙 을 바탕 으로 응답 내용 을 연결 하여 클 라 이언 트 에 출력
  • 코드 는 다음 과 같 습 니 다:
    `
    # coding:utf-8

    import socket
    import re

    from multiprocessing import Process

    HTML_ROOT_DIR = './static'


    class WebServer(object):
    '''
    webserver
    '''

    def __init__(self):
    self.sock_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    self.sock_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    def start(self):
    self.sock_server.listen(128)
    while True:
    sock_client, addr = self.sock_server.accept()
    print('[%s,%s] ......' % addr)
    handle_client_process = Process(target=self.handle_client, args=(sock_client,))
    handle_client_process.start()
    sock_client.close()

    def handle_client(self, sock_client):
    ''' '''
    recv_data = sock_client.recv(1024)
    #print(' :', recv_data)
    req_lines = recv_data.splitlines()
    #for line in req_lines:
    # print(line)

    req_start_line = req_lines[0]
    #print(req_start_line.decode('utf-8'))
    file_name = re.match(r'\w+ +(/[^ ]*) ', req_start_line.decode('utf-8')).group(1)
    if '/' == file_name:
    file_name = "/index.html"

    try:
    file = open(HTML_ROOT_DIR + file_name, 'rb')
    except IOError:
    resp_start_line = 'HTTP/1.1 404 Not Found\r
    '
    resp_headers = 'Server: My Web Server\r
    '
    resp_body = 'The file is not found!'
    else:
    file_data = file.read()
    file.close()

    resp_start_line = 'HTTP/1.1 200 OK\r
    '
    resp_headers = 'Server: My Web Server\r
    '
    resp_body = file_data.decode('utf-8')

    #
    resp_data = resp_start_line + resp_headers + '\r
    ' + resp_body
    #print(' :', resp_data)

    # response
    sock_client.send(bytes(resp_data, 'utf-8'))

    #
    sock_client.close()

    def bind(self, port):
    self.sock_server.bind(('', port))


    def main():
    webServer = WebServer()
    webServer.bind(8000)
    webServer.start()


    if __name__ == '__main__':
    main()
    ` 
  • 주소 표시 줄 입력: 127.0.0.1: 8000
  • 2. 동적 자원
    주요 사고방식 은 다음 과 같다.
  • socket 서비스 감청 클 라 이언 트 연결 열기
  • 다 중 프로 세 스 방식 으로 동시 연결 처리
  • 메시지 분석 규칙 을 바탕 으로. py 로 끝 나 는 요청 이 라면 해당 모듈 에 자동 으로 배포 하여 처리 합 니 다
  • 웹 서버, 코드 는 다음 과 같 습 니 다.
    `
    # coding:utf-8

    import socket
    import re
    import sys

    from multiprocessing import Process

    HTML_ROOT_DIR = './static'
    WSGI_PY = './wsgipy'

    class WebServer(object):
    '''
    webserver
    '''

    def __init__(self):
    self.sock_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    self.sock_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    def start(self):
    self.sock_server.listen(128)
    while True:
    sock_client, addr = self.sock_server.accept()
    print('[%s,%s] ......' % addr)
    handle_client_process = Process(target=self.handle_client, args=(sock_client,))
    handle_client_process.start()
    sock_client.close()

    def start_response(self, status, headers):
    """
    status = "200 OK"
    headers = [
    ("Content-Type", "text/plain")
    ]
    star
    """
    resp_headers = 'HTTP/1.1 ' + status + '\r
    '
    for header in headers:
    resp_headers += '%s: %s\r
    ' % header

    self.resp_headers = resp_headers

    def handle_client(self, sock_client):
    ''' '''
    recv_data = sock_client.recv(1024)
    #print(' :', recv_data)
    req_lines = recv_data.splitlines()
    #for line in req_lines:
    # print(line)

    req_start_line = req_lines[0]
    #print(req_start_line.decode('utf-8'))
    file_name = re.match(r'\w+ +(/[^ ]*) ', req_start_line.decode('utf-8')).group(1)
    method = re.match(r'(\w+) +/[^ ]*',req_start_line.decode("utf-8")).group(1)

    if file_name.endswith('.py'):
    try:
    m = __import__(file_name[1:-3])
    except Exception:
    self.resp_headers = 'HTTP/1.1 404 Not Found\r
    '
    resp_body = 'not found'
    else:
    env = {
    'PATH_INFO': file_name,
    'METHOD': method
    }
    resp_body = m.application(env, self.start_response)
    resp_data = self.resp_headers+'\r
    '+resp_body
    else:
    if '/' == file_name:
    file_name = '/index.html'

    try:
    file = open(HTML_ROOT_DIR + file_name, 'rb')
    except IOError:
    resp_start_line = 'HTTP/1.1 404 Not Found\r
    '
    resp_headers = 'Server: My Web Server\r
    '
    resp_body = 'The file is not found!'
    else:
    file_data = file.read()
    file.close()

    resp_start_line = 'HTTP/1.1 200 OK\r
    '
    resp_headers = 'Server: My Web Server\r
    '
    resp_body = file_data.decode('utf-8')

    #
    resp_data = resp_start_line + resp_headers + '\r
    ' + resp_body
    #print(' :', resp_data)

    # response
    sock_client.send(bytes(resp_data, 'utf-8'))

    #
    sock_client.close()

    def bind(self, port):
    self.sock_server.bind(('', port))


    def main():
    sys.path.insert(1,WSGI_PY)
    webServer = WebServer()
    webServer.bind(8000)
    webServer.start()


    if __name__ == '__main__':
    main()

    `

    helloworld.py:
    `
    # coding:Utf-8

    def application(env,start_response):
    status = '200 OK'
    headers = [
    ('Content-Type','text/plain')
    ]
    start_response(status,headers)
    return 'hello world'
    `  

      1、 .py , :m = __import__('filename') , , 。

      2、 、 ;application(env,start_response) env request ,start_response web , start_response(status,headers) headers web , web status、headers response

      3、 response_body, return 'hello world', 2 status、headers response data

     

    github:python

     

    :https://www.cnblogs.com/tianboblog/p/7279884.html

    좋은 웹페이지 즐겨찾기