python實現外部靜態服務器,瀏覽器通過HTTP與之通信

    因爲網絡間通信是基於TCP協議傳輸數據的,而服務器與瀏覽器之間通信是基於HTTP協議的,那麼下面基於python實現一個tcp服務器,瀏覽器可以基於http協議進行發送請求和解析。展示瀏覽器返回一個固定頁面和HTML頁面案例。

1.服務器只能返回固定頁面給請求者

import socket


def handle_client(client_socket):
    "爲一個客戶端進行服務"
    recv_data = client_socket.recv(1024).decode("utf-8")
    request_header_lines = recv_data.splitlines()
    for line in request_header_lines:
        print(line)

    # 組織相應 頭信息(header)
    response_headers = "HTTP/1.1 200 OK\r\n"  # 200表示找到這個資源
    response_headers += "\r\n"  # 用一個空的行與body進行隔開
    # 組織 內容(body)
    response_body = "hello world"

    response = response_headers + response_body
    client_socket.send(response.encode("utf-8"))
    client_socket.close()


def main():
    "作爲程序的主控制入口"

    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 設置當服務器先close 即服務器端4次揮手之後資源能夠立即釋放,這樣就保證了,下次運行程序時 可以立即綁定7788端口
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server_socket.bind(("", 7788))
    server_socket.listen(128)
    while True:
        client_socket, client_addr = server_socket.accept()
        handle_client(client_socket)


if __name__ == "__main__":
    main()

使用“網路調試助手"作爲TCP 客戶端發送請求給服務器,服務器將固定返回基於http協議格式的hello,world給所有的請求者。

        使用瀏覽器基於HTTP協議訪問該服務器如下,服務器將固定返回基於http協議格式的hello,world給所有的請求者。這裏因爲瀏覽器可以解析http協議的格式文件,所以可以通過網頁的形式展示出來hello,world。當然如果瀏覽器返回一個完整的網頁,那麼同樣瀏覽器也可以解析整個網頁,這就是我們日常使用的服務器與瀏覽器基於http協議的通信啦。

2.服務器返回一個網頁頁面給請求者

瀏覽器通過http協議請求該TCP服務器,該服務器返回一個網頁頁面給瀏覽器,瀏覽器解析以後顯示到前端。

import socket

def service_client(new_socket):
    """爲這個客戶端返回數據"""

    # 1. 接收瀏覽器發送過來的請求 ,即http請求
    # GET / HTTP/1.1
    # .....
    request = new_socket.recv(1024)
    print(">>>" * 50)
    print(request)

    # 2. 返回http格式的數據,給瀏覽器
    # 2.1 準備發送給瀏覽器的數據---header
    response = "HTTP/1.1 200 OK\r\n"
    response += "\r\n"
    # 2.2 準備發送給瀏覽器的數據---boy
    # response += "hahahhah"

    f = open("./html/index.html", "rb")  #讀取的這個文件是我們提前放在程序當前目錄下的,用來測試的文件。
    html_content = f.read()
    f.close()

    # 將response header發送給瀏覽器
    new_socket.send(response.encode("utf-8"))
    # 將response body發送給瀏覽器
    new_socket.send(html_content)  #注意這裏send的數據沒有encode,文件open的方式就是rb,二進制格式

    # 關閉套接
    new_socket.close()


def main():
    """用來完成整體的控制"""
    # 1. 創建套接字
    tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 設置當服務器先close 即服務器端4次揮手之後資源能夠立即釋放,這樣就保證了,下次運行程序時 可以立即綁定7890端口
    tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    # 2. 綁定
    tcp_server_socket.bind(("", 7890))

    # 3. 變爲監聽套接字
    tcp_server_socket.listen(128)

    while True:
        # 4. 等待新客戶端的鏈接
        new_socket, client_addr = tcp_server_socket.accept()

        # 5. 爲這個客戶端服務
        service_client(new_socket)

    # 關閉監聽套接字
    tcp_server_socket.close()


if __name__ == "__main__":
    main()

使用瀏覽器訪問服務器,因爲這裏我定義的是服務器固定返回一個網頁(這個網頁使我們提前放在服務器上的。),所以只要你訪問的是這個服務器,這個端口 ,所有的返回都是一樣。 所以,你訪問的網址,可以任意定義,都不會影響這個訪問結果,比如http://127.0.0.1:7890/dfsdf/aaaahttp://127.0.0.1:7890/aaa/index 等結果都是一樣的。

  如下服務器端顯示了瀏覽器的get請求,但是注意,實際我們訪問一次,但是服務器顯示瀏覽器發送了多次get請求,這是爲什麼呢?

尖叫提示:當瀏覽器讀取到index首頁的HTML源碼後,它會解析HTML,顯示頁面,然後,根據HTML裏面的各種鏈接,再發送HTTP請求給新浪服務器,拿到相應的圖片、視頻、Flash、JavaScript腳本、CSS等各種資源,最終顯示出一個完整的頁面。所以我們在下面能看到很多額外的HTTP請求。

D:\software\python3\python.exe D:/pythoyworkspace/file_demo/Class_Demo/pachong/urllib_Request_Post.py
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
b'GET / HTTP/1.1\r\nHost: 127.0.0.1:7890\r\nConnection: keep-alive\r\nCache-Control: max-age=0\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.80 Safari/537.36\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: zh-CN,zh;q=0.9\r\n\r\n'
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
b'GET /classic.css HTTP/1.1\r\nHost: 127.0.0.1:7890\r\nConnection: keep-alive\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.80 Safari/537.36\r\nAccept: text/css,*/*;q=0.1\r\nReferer: http://127.0.0.1:7890/\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: zh-CN,zh;q=0.9\r\n\r\n'
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
b'GET /images/qt-logo.png HTTP/1.1\r\nHost: 127.0.0.1:7890\r\nConnection: keep-alive\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.80 Safari/537.36\r\nAccept: image/webp,image/apng,image/*,*/*;q=0.8\r\nReferer: http://127.0.0.1:7890/\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: zh-CN,zh;q=0.9\r\n\r\n'
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
b'GET /images/trolltech-logo.png HTTP/1.1\r\nHost: 127.0.0.1:7890\r\nConnection: keep-alive\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.80 Safari/537.36\r\nAccept: image/webp,image/apng,image/*,*/*;q=0.8\r\nReferer: http://127.0.0.1:7890/\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: zh-CN,zh;q=0.9\r\n\r\n'
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
b'GET /favicon.ico HTTP/1.1\r\nHost: 127.0.0.1:7890\r\nConnection: keep-alive\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.80 Safari/537.36\r\nAccept: image/webp,image/apng,image/*,*/*;q=0.8\r\nReferer: http://127.0.0.1:7890/\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: zh-CN,zh;q=0.9\r\n\r\n'

 

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