Python之socket : Python的TCP支持與創建TCP服務端 模擬用戶瀏覽器與服務器交互

描述:

可以用一個小故事來生動描述用戶與服務器交互的原理   移動公司式理解

 

要能辦理用戶手機業務需求  首先要先開一個移動公司, 有一個總檯(socket_server= socket.socket())   移動公司建立了之後要有自己的專用電話號碼(移動是10086, 聯通是10010),用戶才能知道怎麼樣能找到我們辦理業務(socket_server.bind(('', 8080))), 綁定了自己的專用號碼之後就要時時監聽着電話,有用戶打電話辦理業務好及時知道(socket_server.listen(128)), 有用戶打進來了總檯就要接受用戶,讓用戶打進來,然後就會派一個專門的客服人員負責處理用戶的需求(clint_socket,adress= socket_server.accept())      (大家都知道  撥打10086時候  剛開始是總檯說話(socket_server)接待自己, 然後自己要辦理業務,總檯就會分派一個客服人員(clint_socket)爲自己辦理業務   以後的服務都是客服人員在辦理  自己說需求  客服人員辦理之後給自己反饋)   然後客服人員接收用戶需求(clint_socket.recv(4096))   接受用戶需求之後  客服人員會根據用戶說的話  挑選出用戶要辦理的業務(從用戶請求中獲取資源路徑)  才能精確的爲客戶辦理業務, 並且把結果反饋給客戶(返回響應信息給瀏覽器 clint_socket.send(data))   

多線程是因爲用戶會有很多        

while True是因爲用戶可能不止要辦理一項業務

 

 

下面這個圖全面展示了TCP協議下瀏覽器與服務器之間的交互過程

 

提前準備 :我提前創建了一個templates目錄  並且在裏面寫了兩個HTML文件

面向過程:

 

import socket
import re
import threading


def muit_yonghu(s1):
    request = s1.recv(4096)
    print(request)
    print(type(request))
    # 請求頭格式
    data = "HTTP/1.1 200 OK\r\nServer: PWS3.0\r\n\r\n"
    # 獲取用戶請求信息中的路徑信息
    w = re.findall(r'GET (.*?) HTTP/1.1\r\nHost: loc', request.decode())
    print(w[0])
    if w[0] == '/':
        data = data + 'nav.html'
    else:
        # 拼接響應數據
        try:
            with open(f'./templates/{w[0]}', 'rb') as f:
                res = f.read()
                data = data + res.decode()
        except:
            data = data + '<h1>404 Page Not Found</h1>'

    # 把信息傳給瀏覽器
    s1.send(data.encode())
    s1.close()


def server():
    # 創建服務器
    s = socket.socket()
    # 設置端口重用
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    # 服務器綁定端口便於客戶訪問
    s.bind(('', 8000))
    while True:
        # 設置爲監聽模式,當用戶訪問時就會知道
        s.listen(128)
        # 當用戶訪問時,給用戶分配一個分機,並且獲取用戶IP
        s1, a = s.accept()
        print(f'{a}用戶已登錄')
        #獲取瀏覽器發來的請求信息
        t = threading.Thread(target = muit_yonghu, args = (s1, ))
        t.start()




if __name__ == '__main__':

    server()


面向對象:

class So(object):

    def __init__(self):
        #創建套接字
        s = socket.socket()
        #設置端口複用
        s.setsockopt(socket.SOL_SOCKET, socket.SOCK_STREAM, 1)
        #綁定端口
        s.bind(('', 8080))
        #設置監聽模式
        s.listen(128)
        self.client_threed(s)


    def client_threed(self, s):
        while True:
            #讓用戶訪問並給用戶分配一個分機
            self.s1, a = s.accept()
            print(f'{a}用戶已登錄')
            t = threading.Thread(target=self.clint)
            t.start()


    def clint(self):
        while True:
            #接收用戶請求信息
            data = self.s1.recv(4096)
            data = data.decode()
            # print(data)
            #從請求信息中獲取資源路徑
            clint_data = re.findall(r'ET /(.*?) HTTP/1.1', data)
            # print(clint_data[0])
            send_data = "HTTP/1.1 200 OK\r\nServer: PWS3.0\r\n\r\n"
            #返回資源給瀏覽器 try:如果用戶清秀資源路徑不存在  返回404
            try:
                with open(f'./templates/{clint_data[0]}', 'rb') as f:
                    w = f.read()
                send_data = send_data + w.decode()
            except:
                send_data = send_data + '<h1>404 Page Not Found</h1>'
            #將相應信息返回給用戶
            self.s1.send(send_data.encode())
        

 

if __name__ == '__main__':
    s = So()

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章