1. 程式人生 > >Python網路程式設計——升級版--HttpServer V2.0

Python網路程式設計——升級版--HttpServer V2.0

HTTPServer V2.0
1.接收客戶S端請求
2.解析客戶端請求
3.組織資料,形成http response
4.將資料傳送給客戶端

相比 V1.0升級點:
1.採用多執行緒併發接收多個客戶端請求
2.基本的請求解析,根據請求返回響應的內容
3.除了可以請求靜態網頁也可以請求簡單的資料
4.將功能封裝在類中

技術點:
1.socket tcp 套接字
2.http協議的請求,響應格式
3.執行緒併發的建立方法
4.類的基本使用

程式碼如下:

#coding=utf-8
'''
http server v2.0
1.多執行緒併發
2.可以請求簡單資料
3.能進行簡單請求解析
4.結構使用類程序封裝
'''
from socket import * 
from threading import Thread
import sys
import traceback

#httpserver類,封裝具體的伺服器功能
class httpserver(object):
    def __init__(self,server_addr,static_dir):
        #增添伺服器物件屬性
        self.server_address = server_addr
        self.static_dir = static_dir
        self.ip = server_addr[0]
        self.port = server_addr[1]
        #建立套接字
        self.create_socket()

    def create_socket(self):
        self.sockfd = socket()
        self.sockfd.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
        self.sockfd.bind(self.server_address)

    #設定監聽等待客戶端連線
    def serve_forever(self):
        self.sockfd.listen(5)
        print('listen the port %d'%self.port)
        while True:
            try:
                connfd,addr = self.sockfd.accept()
            except KeyboardInterrupt:
                self.sockfd.close()
                sys.exit('伺服器退出')
            except Exception:
                trackback.print_exc()
                continue
            #建立新的執行緒處理請求
            clientThread = Thread(target = self.handleRequest,args=(connfd,))
            clientThread.setDaemon(True)
            clientThread.start()
    #客戶端請求函式
    def handleRequest(self,connfd):
        #接收客戶端請求
        request = connfd.recv(4096)
        #解析請求內容
        requestHeaders = request.splitlines()
        print(connfd.getpeername(),':',requestHeaders[0])
        #獲取具體請求內容
        getRequest = str(requestHeaders[0]).split(' ')[1]

        if getRequest == '/' or getRequest[-5:] == '.html':
            self.get_html(connfd,getRequest)
        else:
            self.get_data(connfd,getRequest)

        connfd.close()

    def get_html(self,connfd,getRequest):
        if getRequest == '/':
            filename = self.static_dir + '/index.html'
        else:
            filename = self.static_dir + getRequest
        try:
            f = open(filename)
        except IOError:
            response = 'HTTP/1.1 404 not found\r\n'
            response += '\r\n'
            response += '=======sorry not found======='
        else:
            response = 'HTTP/1.1 200 OK\r\n'
            response += '\r\n'
            response += f.read()
        finally:
            connfd.send(response.encode())

    def get_data(self,connfd,getRequest):
        urls = ['/time','/tedu','/python']
        if getRequest in urls:
            response = 'HTTP/1.1 200 OK\r\n'
            response += '\r\n'
            if getRequest == '/time':
                import time
                response += time.ctime()
            elif getRequest == '/tedu':
                response += 'welcome to tarena'
            elif getRequest == '/python':
                response += '人生苦短我用python'
        else:
            response = 'HTTP/1.1 404 not found\r\n'
            response += '\r\n'
            response += '=======sorry not found the data======='
        connfd.send(response.encode())

if __name__=='__main__':
    #伺服器IP
    server_addr = ('0.0.0.0',5000)
    #靜態資料夾儲存目錄
    static_dir = ('./static')

    #生成物件
    httpd = httpserver(server_addr,static_dir)
    #啟動伺服器
    httpd.serve_forever()