天天看點

簡單的HTTP伺服器搭建 | 手把手教你入門Python之一百一十

上一篇: 程序池的使用 | 手把手教你入門Python之一百零九 下一篇: Http請求頭 | 手把手教你入門Python之一百一十一 本文來自于千鋒教育在阿裡雲開發者社群學習中心上線課程 《Python入門2020最新大課》 ,主講人姜偉。

簡單的HTTP伺服器搭建

HTTP協定:HyperText Transfer Protocol 超文本傳輸協定

協定的作用就是用來傳輸超文本 HTML(HyperTextMarkupLanguage)

HTML:超文本标記語言

HTTP:用來傳輸超文本的一個協定

以Chrome為例,在網頁空白處點選右鍵,選擇檢查,就可以顯示開發者工具,其中:

  • Elements顯示網頁的結構
  • Network顯示浏覽器和伺服器的通信

點Network,確定第一個小紅燈亮着,Chrome就會記錄所有浏覽器和伺服器之間的通信:

簡單的HTTP伺服器搭建 | 手把手教你入門Python之一百一十

General中包含了一些概覽資訊,請求頭和響應頭在請求發送過程中的詳細過程如下:

簡單的HTTP伺服器搭建 | 手把手教你入門Python之一百一十
import socket

# HTTP 伺服器都是基于TCP的socket連結
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

server_socket.bind(('192.168.31.199', 9090))
server_socket.listen(128)

# 擷取的資料是一個元組,元組裡有兩個元素
# 第 0 個元素是 用戶端的socket連結
# 第 1 個元素是 用戶端的ip位址和端口号
client_socket, client_addr = server_socket.accept()

# 從用戶端的 socket 裡擷取資料
data = client_socket.recv(1024).decode('utf8')

# 給用戶端傳回消息
client_socket.send('hello world'.encode('utf8'))
print(data)           

在浏覽器中通路結果如下:

簡單的HTTP伺服器搭建 | 手把手教你入門Python之一百一十

浏覽器回報bad response,說明需要先設定響應頭

import socket

# HTTP 伺服器都是基于TCP的socket連結
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

server_socket.bind(('192.168.31.199', 9090))
server_socket.listen(128)

# 擷取的資料是一個元組,元組裡有兩個元素
# 第 0 個元素是 用戶端的socket連結
# 第 1 個元素是 用戶端的ip位址和端口号
client_socket, client_addr = server_socket.accept()

# 從用戶端的 socket 裡擷取資料
data = client_socket.recv(1024).decode('utf8')
print('接收到的資料{}'.format(data))

# 傳回内容之前,需要先設定HTTP響應頭

# 設定一個響應頭就換一行
client_socket.send('HTTP/1.1 200 OK\n'.encode('utf8'))
client_socket.send('content-type:text/html\n'.encode('utf8'))

# 所有的響應頭設定完成以後,再換行
client_socket.send('\n'.encode('utf8'))

# 發送内容
client_socket.send('hello world'.encode('utf8'))           
簡單的HTTP伺服器搭建 | 手把手教你入門Python之一百一十

将代碼中的位址改為0.0.0.0:

import socket

# HTTP 伺服器都是基于TCP的socket連結
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

server_socket.bind(('0.0.0.0', 9090))
server_socket.listen(128)

# 擷取的資料是一個元組,元組裡有兩個元素
# 第 0 個元素是 用戶端的socket連結
# 第 1 個元素是 用戶端的ip位址和端口号
client_socket, client_addr = server_socket.accept()

# 從用戶端的 socket 裡擷取資料
data = client_socket.recv(1024).decode('utf8')
print('接收到{}的資料{}'.format(client_addr[0], data))

# 傳回内容之前,需要先設定HTTP響應頭

# 設定一個響應頭就換一行
client_socket.send('HTTP/1.1 200 OK\n'.encode('utf8'))
client_socket.send('content-type:text/html\n'.encode('utf8'))

# 所有的響應頭設定完成以後,再換行
client_socket.send('\n'.encode('utf8'))

# 發送内容
client_socket.send('hello world'.encode('utf8'))           

在雲伺服器中運作此py檔案,然後在浏覽器中通路伺服器的位址的相應端口,通路效果如下:

簡單的HTTP伺服器搭建 | 手把手教你入門Python之一百一十

雲伺服器中将列印出通路頭和通路者位址資訊:

簡單的HTTP伺服器搭建 | 手把手教你入門Python之一百一十

此時的代碼隻能接收一次請求,可以在代碼中添加死循環,并将端口設定方式改為動态設定:

import socket

port = int(input('請輸入端口号:'))
# HTTP 伺服器都是基于TCP的socket連結
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

server_socket.bind(('0.0.0.0', port))
server_socket.listen(128)
print('server is running at 0.0.0.0:{}'.format(port))

# 擷取的資料是一個元組,元組裡有兩個元素
# 第 0 個元素是 用戶端的socket連結
# 第 1 個元素是 用戶端的ip位址和端口号
while True:
    client_socket, client_addr = server_socket.accept()

    # 從用戶端的 socket 裡擷取資料
    data = client_socket.recv(1024).decode('utf8')
    print('接收到{}的資料{}'.format(client_addr[0], data))

    # 傳回内容之前,需要先設定HTTP響應頭

    # 設定一個響應頭就換一行
    client_socket.send('HTTP/1.1 200 OK\n'.encode('utf8'))
    client_socket.send('content-type:text/html\n'.encode('utf8'))

    # 所有的響應頭設定完成以後,再換行
    client_socket.send('\n'.encode('utf8'))

    # 發送内容
    client_socket.send('hello world'.encode('utf8'))           

在伺服器中啟動,并使用8090端口:

簡單的HTTP伺服器搭建 | 手把手教你入門Python之一百一十

浏覽器中通路結果:

簡單的HTTP伺服器搭建 | 手把手教你入門Python之一百一十

調整傳回的内容為通路者的位址:

import socket

port = int(input('請輸入端口号:'))
# HTTP 伺服器都是基于TCP的socket連結
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

server_socket.bind(('0.0.0.0', port))
server_socket.listen(128)
print('server is running at 0.0.0.0:{}'.format(port))

# 擷取的資料是一個元組,元組裡有兩個元素
# 第 0 個元素是 用戶端的socket連結
# 第 1 個元素是 用戶端的ip位址和端口号
while True:
    client_socket, client_addr = server_socket.accept()

    # 從用戶端的 socket 裡擷取資料
    data = client_socket.recv(1024).decode('utf8')
    print('接收到{}的資料{}'.format(client_addr[0], data))

    # 傳回内容之前,需要先設定HTTP響應頭

    # 設定一個響應頭就換一行
    client_socket.send('HTTP/1.1 200 OK\n'.encode('utf8'))
    client_socket.send('content-type:text/html\n'.encode('utf8'))

    # 所有的響應頭設定完成以後,再換行
    client_socket.send('\n'.encode('utf8'))

    # 發送内容
    client_socket.send(client_addr[0].encode('utf8'))           

浏覽器通路效果:

簡單的HTTP伺服器搭建 | 手把手教你入門Python之一百一十

配套視訊