python Http的Socket編程

Socket之靜態http服務器編程

  1. 創建socket套接字
  2. 綁定端口號
  3. 設置監聽
  4. 等待客戶端連接請求
  5. 封裝http響應報文格式
  6. 使用客戶端的套接字回覆消息
  7. 關閉客戶端連接
import socket

if __name__ == '__main__':
    # 創建tcp服務端套接字
    tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 設置端口號複用, 程序退出端口立即釋放
    tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    # 綁定端口號
    tcp_server_socket.bind(("", 8001))
    # 設置監聽
    tcp_server_socket.listen(128)
    while True:
        # 等待接受客戶端的連接請求
        new_socket, ip_port = tcp_server_socket.accept()
        # 代碼執行到此,說明連接建立成功
        recv_client_data = new_socket.recv(4096)
        # 對二進制數據進行解碼
        recv_client_content = recv_client_data.decode("utf-8")
        print(recv_client_content)

        with open("static/index.html", "rb") as file:
            # 讀取文件數據
            file_data = file.read()


        # 響應行
        response_line = "HTTP/1.1 200 OK\r\n"
        # 響應頭
        response_header = "Server: Python-server\r\n"

        # 響應體
        response_body = file_data

        # 拼接響應報文
        response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body
        # 發送數據
        new_socket.send(response_data)

        # 關閉服務與客戶端的套接字
        new_socket.close()



計算機網絡基礎知識介紹:

計算機網絡

HTTP協議介紹

  超文本傳輸協議(HTTP,HyperText Transfer Protocol)是互聯網上應用最爲廣泛的一種網絡協議。所有的www文件都必須遵守這個標準。

1、HTTP 協議包括哪些請求?

GET:請求讀取由URL所標誌的信息。

POST:給服務器添加信息(如註釋)。

PUT:在給定的URL下存儲一個文檔。

DELETE:刪除給定的URL所標誌的資源。

2、HTTP 中, POST 與 GET 的區別

1)Get是從服務器上獲取數據,Post是向服務器傳送數據。

2)Get是把參數數據隊列加到提交表單的Action屬性所指向的URL中,值和表單內各個字段一一對應,在URL中可以看到。

3)Get傳送的數據量小,不能大於2KB;Post傳送的數據量較大,一般被默認爲不受限制。

4)根據HTTP規範,GET用於信息獲取,而且應該是安全的和冪等的。

I. 所謂 安全的 意味着該操作用於獲取信息而非修改信息。換句話說,GET請求一般不應產生副作用。就是說,它僅僅是獲取資源信息,就像數據庫查詢一樣,不會修改,增加數據,不會影響資源的狀態。

II. 冪等 的意味着對同一URL的多個請求應該返回同樣的結果。

3、get請求報文

組成:

  1. 請求行
  2. 請求頭
  3. 空行

原始報文:(每行末尾都有一個 ‘\r\n’)

GET / HTTP/1.1 \r\n

Host: localhost:8001\r\n  
Connection: keep-alive\r\n
Upgrade-Insecure-Requests: 1\r\n
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36\r\n
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\n
Accept-Encoding: gzip, deflate\r\n
Accept-Language: zh-CN,zh;q=0.9\r\n
Cookie: pgv_pvi=1246921728; \r\n

\r\n  (請求頭信息後面還有一個單獨的’\r\n’不能省略)
  • 請求行
    GET / HTTP/1.1 \r\n
    分別代表:請求方式、資源路徑、http協議版本
  • 請求頭
    每一行都是一個鍵值對+\r\n組成
說明
Host localhost:8001 服務器的主機地址和端口號,默認是80
Connection keep-alive 和服務端保持長連接
Upgrade-Insecure-Requests 1 讓瀏覽器升級不安全請求,使用https請求
User-Agent Mozilla/5.0… 用戶代理,也就是客戶端的名稱
Accept text/html, application/xhtml+xml,application/xml;… 可接受的數據類型
Accept-Encoding gzip, deflate 可接受的壓縮格式
Accept-Language zh-CN,zh;q=0.9 可接受的語言,q代表權值
Cookie pgv_pvi=1246921728; 登錄用戶的身份標識
  • 空行
    最後要有一個空行\r\n

4、post請求報文

組成:

  1. 請求行
  2. 請求頭
  3. 空行
  4. 請求體

原始報文:(每行末尾都有一個 ‘\r\n’)

POST /adduser HTTP/1.1\r\n
Host: localhost:8001\r\n
Connection: keep-alive\r\n
Content-Type: application/x-www-form-urlencoded\r\n
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36\r\n
\r\n(請求頭信息後面還有一個單獨的’\r\n’不能省略)
// Form Data
username=hello&pass=hello
  • 請求行
    POST /adduser HTTP/1.1\r\n
    分別代表:請求方式、資源路徑、http協議版本
  • 請求頭
    每一行都是一個鍵值對+\r\n組成,其它參數同get請求
說明
Content-Type application/x-www-form-urlencoded 告訴服務端請求的數據類型
  • 空行
    與請求體之間要有一個空行\r\n

  • 請求體
    表單默認的數據格式: username=hello&pass=hello

5、響應報文

組成:

  1. 響應行
  2. 響應頭
  3. 空行
  4. 響應體

原始報文:(每行末尾都有一個 ‘\r\n’)

---響應頭----
HTTP/1.1 200 OK\r\n

---響應行----
Server: apache\r\n
Content-Type: text/html; charset=UTF-8\r\n
Transfer-Encoding: chunked\r\n
Connection: keep-alive\r\n
Date: Sun, 28 Jun 2020 09:01:10 GMT\r\n
---空行----
\r\n(響應頭信息後面還有一個單獨的’\r\n’不能省略)

---響應體----
<!DOCTYPE html><html lang=“en”></html>
  • 響應行
    HTTP/1.1 200 OK\r\n
    分別代表:HTTP協議版本、狀態碼、狀態描述
  • 響應頭
    每一行都是一個鍵值對+\r\n組成
說明
Server apache 服務器名稱
Content-Type text/html; charset=UTF-8 內容類型
Transfer-Encoding chunked 發送結束的標記是0\r\n, Content-Length表示服務端確定發送給客戶端的內容大小,但是二者只能用其一。
Connection keep-alive 和客戶端保持長連接
Date Sun, 28 Jun 2020 09:01:10 GMT 服務端的響應時間
  • 空行
    與請求體之間要有一個空行\r\n

  • 響應體
    <!DOCTYPE html><html lang=“en”> …</html>響應給客戶端的數據

三種報文對比

在這裏插入圖片描述

其它請求體內容格式詳見:

POST請求報文數據格式

6、Connection參數,長、短連接

  我們知道HTTP協議採用“請求-應答”模式,當使用普通模式,即非KeepAlive模式時,每個請求/應答客戶和服務器都要新建一個連接,完成之後立即斷開連接(HTTP協議爲無連接的協議);當使用Keep-Alive模式(又稱持久連接、連接重用)時,Keep-Alive功能使客戶端到服務器端的連接持續有效,當出現對服務器的後續請求時,Keep-Alive功能避免了建立或者重新建立連接。

在這裏插入圖片描述

  如上圖中,左邊的是關閉Keep-Alive的情況,每次請求都需要建立連接,然後關閉連接;右邊的則是Keep-Alive,在第一次建立請求之後保持連接,然後後續的就不需要每次都建立、關閉連接了, 啓用Keep-Alive模式肯定更高效,性能更高,因爲避免了建立/釋放連接的開銷 。

  http 1.0中默認是關閉的,需要在http頭加入"Connection: Keep-Alive",才能啓用Keep-Alive;http 1.1中默認啓用Keep-Alive,如果加入"Connection: close ",才關閉。目前大部分瀏覽器都是用http1.1協議,也就是說默認都會發起Keep-Alive的連接請求了,所以是否能完成一個完整的Keep- Alive連接就看服務器設置情況。

7、常見http狀態碼

HTTP 狀態碼是用於表示web服務器響應狀態的3位數字代碼。

狀態碼 說明
200 請求成功
307 重定向
400 錯誤的請求,請求地址或者參數有誤
404 請求資源在服務器不存在
500 服務器內部源代碼出現錯誤

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