日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

网络编程学习

發布時間:2024/3/26 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 网络编程学习 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

python高級——IP 地址的介紹

  • IP 地址的作用
      • 1. IP 地址的概念
      • 2. IP 地址的表現形式
      • 3. IP 地址的作用
      • 4. 查看 IP 地址
      • 5檢查網絡是否正常
  • TCP 的介紹
    • 1. 網絡應用程序之間的通信流程
    • 2. TCP 的概念
    • 3. TCP 的特點
    • 4. 總結
  • socket 的介紹
    • socket 的作用
    • socket 使用場景
  • TCP 網絡應用程序開發流程的介紹
  • TCP 客戶端程序開發流程的介紹
    • 開發 TCP 客戶端程序開發步驟:
    • socket 類的介紹
    • TCP 客戶端程序開發示例代碼
    • 小結
  • TCP 服務端程序開發流程的介紹
    • socket 類的介紹
    • TCP 服務端程序開發示例代碼
    • 小結
  • TCP網絡應用程序的注意點
  • socket之send和recv原理剖析
    • 認識TCP socket的發送和接收緩沖區
    • send原理剖析
    • recv原理剖析
    • send和recv原理剖析圖
  • URL
    • HTTP 請求報文
    • HTTP響應報文
    • 搭建Python自帶靜態Web服務器
    • 靜態Web服務器-返回固定頁面數據
    • 靜態Web服務器-返回指定頁面數據
    • 靜態Web服務器-多任務版
    • 靜態Web服務器-面向對象開發
    • 靜態Web服務器-命令行啟動動態綁定端口號

IP 地址的作用

1. IP 地址的概念

IP 地址就是標識網絡中設備的一個地址,好比現實生活中的家庭地址。
網絡中的設備效果圖:

2. IP 地址的表現形式

IP 地址分為兩類: IPv4 和 IPv6

IPv4 是目前使用的ip地址

IPv6 是未來使用的ip地址

IPv4 是由點分十進制組成

IPv6 是由冒號十六進制組成

3. IP 地址的作用

IP 地址的作用是標識網絡中唯一的一臺設備的,也就是說通過IP地址能夠找到網絡中某臺設備。

4. 查看 IP 地址

Linux 和 mac OS 使用 ifconfig 這個命令
Windows 使用 ipconfig 這個命令
說明:
ifconfig 和 ipconfig 都是查看網卡信息的,網卡信息中包括這個設備對應的IP地址
說明:
192.168.1.107是設備在網絡中的IP地址
127.0.0.1表示本機地址,提示:如果和自己的電腦通信就可以使用該地址。
127.0.0.1該地址對應的域名是localhost,域名是 ip 地址的別名,通過域名能解析出一個對應的ip地址。

5檢查網絡是否正常

檢查網絡是否正常使用 ping 命令
說明:
ping www.baidu.com 檢查是否能上公網
ping 當前局域網的ip地址 檢查是否在同一個局域網內
ping 127.0.0.1 檢查本地網卡是否正常
IP 地址的作用是標識網絡中唯一的一臺設備的
IP 地址的表現形式分為: IPv4 和 IPv6
查看網卡信息:ifconfig
檢查網絡: ping

TCP 的介紹

1. 網絡應用程序之間的通信流程

通過 IP 地址能夠找到對應的設備,然后再通過端口號找到對應的端口,再通過端口把數據傳輸給應用程序,這里要注意,數據不能隨便發送,在發送之前還需要選擇一個對應的傳輸協議,保證程序之間按照指定的傳輸規則進行數據的通信, 而這個傳輸協議就是我們今天學習的 TCP。

2. TCP 的概念

TCP 的英文全拼(Transmission Control Protocol)簡稱傳輸控制協議,它是一種面向連接的、可靠的、基于字節流的傳輸層通信協議。
TCP 通信步驟:

創建連接
傳輸數據
關閉連接
說明:

TCP 通信模型相當于生活中的’打電話‘,在通信開始之前,一定要先建立好連接,才能發送數據,通信結束要關閉連接。

3. TCP 的特點

面向連接
通信雙方必須先建立好連接才能進行數據的傳輸,數據傳輸完成后,雙方必須斷開此連接,以釋放系統資源。
可靠傳輸
TCP 采用發送應答機制
超時重傳
錯誤校驗
流量控制和阻塞管理

4. 總結

TCP 是一個穩定、可靠的傳輸協議,常用于對數據進行準確無誤的傳輸,比如: 文件下載,瀏覽器上網。

socket 的介紹

socket 的概念
socket (簡稱 套接字) 是進程之間通信一個工具,好比現實生活中的插座,所有的家用電器要想工作都是基于插座進行,進程之間想要進行網絡通信需要基于這個 socket。

socket 的作用

負責進程之間的網絡數據傳輸,好比數據的搬運工。

socket 使用場景

不夸張的說,只要跟網絡相關的應用程序或者軟件都使用到了 socket 。
進程之間網絡數據的傳輸可以通過 socket 來完成, socket 就是進程間網絡數據通信的工具。

TCP 網絡應用程序開發流程的介紹

TCP 網絡應用程序開發分為:
TCP 客戶端程序開發
TCP 服務端程序開發
說明:
客戶端程序是指運行在用戶設備上的程序 服務端程序是指運行在服務器設備上的程序,專門為客戶端提供數據服務。

TCP 客戶端程序開發流程的介紹

開發 TCP 客戶端程序開發步驟:

創建客戶端套接字對象
和服務端套接字建立連接
發送數據
接收數據
關閉客戶端套接字

socket 類的介紹

導入 socket 模塊 import socket

創建客戶端 socket 對象 socket.socket(AddressFamily, Type)

參數說明:

AddressFamily 表示IP地址類型, 分為TPv4和IPv6
Type 表示傳輸協議類型
方法說明:

connect((host, port)) 表示和服務端套接字建立連接, host是服務器ip地址,port是應用程序的端口號
send(data) 表示發送數據,data是二進制數據
recv(buffersize) 表示接收數據, buffersize是每次接收數據的長度

TCP 客戶端程序開發示例代碼

import socket if __name__ == '__main__':# 創建tcp客戶端套接字# 1. AF_INET:表示ipv4# 2. SOCK_STREAM: tcp傳輸協議tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 和服務端應用程序建立連接tcp_client_socket.connect(("192.168.131.62", 8080))# 代碼執行到此,說明連接建立成功# 準備發送的數據send_data = "你好服務端,我是客戶端小黑!".encode("gbk")# 發送數據tcp_client_socket.send(send_data)# 接收數據, 這次接收的數據最大字節數是1024recv_data = tcp_client_socket.recv(1024)# 返回的直接是服務端程序發送的二進制數據print(recv_data)# 對數據進行解碼recv_content = recv_data.decode("gbk")print("接收服務端的數據為:", recv_content)# 關閉套接字tcp_client_socket.close() #執行結果:#b'hello' #接收服務端的數據為: hello #說明#str.encode(編碼格式) 表示把字符串編碼成為二進制 #data.decode(編碼格式) 表示把二進制解碼成為字符串

小結

導入socket模塊
創建TCP套接字‘socket’
參數1: ‘AF_INET’, 表示IPv4地址類型
參數2: ‘SOCK_STREAM’, 表示TCP傳輸協議類型
發送數據‘send’
參數1: 要發送的二進制數據, 注意: 字符串需要使用encode()方法進行編碼
接收數據‘recv’
參數1: 表示每次接收數據的大小,單位是字節
關閉套接字‘socket’表示通信完成

TCP 服務端程序開發流程的介紹

socket 類的介紹

導入 socket 模塊
import socket

創建服務端 socket 對象
socket.socket(AddressFamily, Type)

參數說明:

AddressFamily 表示IP地址類型, 分為TPv4和IPv6
Type 表示傳輸協議類型
方法說明:

bind((host, port)) 表示綁定端口號, host 是 ip 地址,port 是端口號,ip 地址一般不指定,表示本機的任何一個ip地址都可以。
listen (backlog) 表示設置監聽,backlog參數表示最大等待建立連接的個數。
accept() 表示等待接受客戶端的連接請求
send(data) 表示發送數據,data 是二進制數據
recv(buffersize) 表示接收數據, buffersize 是每次接收數據的長度

TCP 服務端程序開發示例代碼

import socketif __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(("", 8989))# 設置監聽# 128:最大等待建立連接的個數, 提示: 目前是單任務的服務端,同一時刻只能服務與一個客戶端,后續使用多任務能夠讓服務端同時服務與多個客戶端,# 不需要讓客戶端進行等待建立連接# listen后的這個套接字只負責接收客戶端連接請求,不能收發消息,收發消息使用返回的這個新套接字來完成tcp_server_socket.listen(128)# 等待客戶端建立連接的請求, 只有客戶端和服務端建立連接成功代碼才會解阻塞,代碼才能繼續往下執行# 1. 專門和客戶端通信的套接字: service_client_socket# 2. 客戶端的ip地址和端口號: ip_portservice_client_socket, ip_port = tcp_server_socket.accept()# 代碼執行到此說明連接建立成功print("客戶端的ip地址和端口號:", ip_port)# 接收客戶端發送的數據, 這次接收數據的最大字節數是1024recv_data = service_client_socket.recv(1024)# 獲取數據的長度recv_data_length = len(recv_data)print("接收數據的長度為:", recv_data_length)# 對二進制數據進行解碼recv_content = recv_data.decode("gbk")print("接收客戶端的數據為:", recv_content)# 準備發送的數據send_data = "ok, 問題正在處理中...".encode("gbk")# 發送數據給客戶端service_client_socket.send(send_data)# 關閉服務與客戶端的套接字, 終止和客戶端通信的服務service_client_socket.close()# 關閉服務端的套接字, 終止和客戶端提供建立連接請求的服務tcp_server_socket.close() #執行結果:#客戶端的ip地址和端口號: ('172.16.47.209', 52472) #接收數據的長度為: 5 #接收客戶端的數據為: hello #說明:#當客戶端和服務端建立連接后,服務端程序退出后端口號不會立即釋放,需要等待大概1-2分鐘。

解決辦法有兩種:

更換服務端端口號
設置端口號復用(推薦大家使用),也就是說讓服務端程序退出后端口號立即釋放。
設置端口號復用的代碼如下:

參數1: 表示當前套接字
參數2: 設置端口號復用選項
參數3: 設置端口號復用選項對應的值
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)

小結

導入socket模塊
創建TCP套接字‘socket’
參數1: ‘AF_INET’, 表示IPv4地址類型
參數2: ‘SOCK_STREAM’, 表示TCP傳輸協議類型
綁定端口號‘bind’
參數: 元組, 比如:(ip地址, 端口號)
設置監聽‘listen’
參數: 最大等待建立連接的個數
等待接受客戶端的連接請求‘accept’
發送數據‘send’
參數: 要發送的二進制數據, 注意: 字符串需要使用encode()方法進行編碼
接收數據‘recv’
參數: 表示每次接收數據的大小,單位是字節,注意: 解碼成字符串使用decode()方法
關閉套接字‘socket’表示通信完成

TCP網絡應用程序的注意點

TCP網絡應用程序的注意點介紹
當 TCP 客戶端程序想要和 TCP 服務端程序進行通信的時候必須要先建立連接
TCP 客戶端程序一般不需要綁定端口號,因為客戶端是主動發起建立連接的。
TCP 服務端程序必須綁定端口號,否則客戶端找不到這個 TCP 服務端程序。
listen 后的套接字是被動套接字,只負責接收新的客戶端的連接請求,不能收發消息。
當 TCP 客戶端程序和 TCP 服務端程序連接成功后, TCP 服務器端程序會產生一個新的套接字,收發客戶端消息使用該套接字。
關閉 accept 返回的套接字意味著和這個客戶端已經通信完畢。
關閉 listen 后的套接字意味著服務端的套接字關閉了,會導致新的客戶端不能連接服務端,但是之前已經接成功的客戶端還能正常通信。
當客戶端的套接字調用 close 后,服務器端的 recv 會解阻塞,返回的數據長度為0,服務端可以通過返回數據的長度來判斷客戶端是否已經下線,反之服務端關閉套接字,客戶端的 recv 也會解阻塞,返回的數據長度也為0。

socket之send和recv原理剖析

認識TCP socket的發送和接收緩沖區

當創建一個TCP socket對象的時候會有一個發送緩沖區和一個接收緩沖區,這個發送和接收緩沖區指的就是內存中的一片空間。

send原理剖析

send是不是直接把數據發給服務端?
不是,要想發數據,必須得通過網卡發送數據,應用程序是無法直接通過網卡發送數據的,它需要調用操作系統接口,也就是說,應用程序把發送的數據先寫入到發送緩沖區(內存中的一片空間),再由操作系統控制網卡把發送緩沖區的數據發送給服務端網卡 。

recv原理剖析

recv是不是直接從客戶端接收數據?
不是,應用軟件是無法直接通過網卡接收數據的,它需要調用操作系統接口,由操作系統通過網卡接收數據,把接收的數據寫入到接收緩沖區(內存中的一片空間),應用程序再從接收緩存區獲取客戶端發送的數據。

send和recv原理剖析圖


說明:
發送數據是發送到發送緩沖區
接收數據是從接收緩沖區 獲取
不管是recv還是send都不是直接接收到對方的數據和發送數據到對方,發送數據會寫入到發送緩沖區,接收數據是從接收緩沖區來讀取,發送數據和接收數據最終是由操作系統控制網卡來完成。

URL

URL的概念

URL的英文全拼是(Uniform Resoure Locator),表達的意思是統一資源定位符,通俗理解就是網絡資源地址,也就是我們常說的網址。
URL的組成部分:
協議部分: https://、http://、ftp://
域名部分: news.163.com
資源路徑部分: /18/1122/10/E178J2O4000189FH.html
域名:域名就是IP地址的別名,它是用點進行分割使用英文字母和數字組成的名字,使用域名目的就是方便的記住某臺主機IP地址。

HTTP 請求報文

HTTP最常見的請求報文有兩種:
GET 方式的請求報文 GET: 獲取web服務器數據
POST 方式的請求報文 POST: 向web服務器提交數據
一個HTTP請求報文可以由請求行、請求頭、空行和請求體4個部分組成。
請求行是由三部分組成:
請求方式
請求資源路徑
HTTP協議版本
GET方式的請求報文沒有請求體,只有請求行、請求頭、空行組成。
POST方式的請求報文可以有請求行、請求頭、空行、請求體四部分組成,注意:POST方式可以允許沒有請求體,但是這種格式很少見

HTTP響應報文

HTTP 狀態碼是用于表示web服務器響應狀態的3位數字代碼。
狀態碼 說明
200 請求成功
307 重定向
400 錯誤的請求,請求地址或者參數有誤
404 請求資源在服務器不存在
500 服務器內部源代碼出現錯誤
一個HTTP響應報文是由響應行、響應頭、空行和響應體4個部分組成。
響應行是由三部分組成:HTTP協議版本 狀態碼 狀態描述,最常見的狀態碼是200

搭建Python自帶靜態Web服務器

靜態Web服務器是什么?
可以為發出請求的瀏覽器提供靜態文檔的程序。
平時我們瀏覽百度新聞數據的時候,每天的新聞數據都會發生變化,那訪問的這個頁面就是動態的,而我們開發的是靜態的,頁面的數據不會發生變化。
如何搭建Python自帶的靜態Web服務器
搭建Python自帶的靜態Web服務器使用 python3 -m http.server 端口號
m選項說明: -m表示運行包里面的模塊,執行這個命令的時候,需要進入你自己指定靜態文件的目錄,然后通過瀏覽器就能訪問對應的 html文件了,這樣一個靜態的web服務器就搭建好了。
訪問搭建的靜態Web服務器
通過瀏覽器訪問搭建的靜態Web服務器
查看瀏覽器和搭建的靜態Web服務器的通信過程
靜態Web服務器是為發出請求的瀏覽器提供靜態文檔的程序,
搭建Python自帶的Web服務器使用python3 –m http.server 端口號 這個命令即可,端口號不指定默認是8000

靜態Web服務器-返回固定頁面數據

開發自己的靜態Web服務器
實現步驟:
編寫一個TCP服務端程序
獲取瀏覽器發送的http請求報文數據
讀取固定頁面數據,把頁面數據組裝成HTTP響應報文數據發送給瀏覽器。
HTTP響應報文數據發送完成以后,關閉服務于客戶端的套接字。
靜態Web服務器-返回固定頁面數據的示例代碼

import socketif __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(("", 9000))# 設置監聽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: PWS1.0\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() 編寫一個TCP服務端程序tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 循環接受客戶端的連接請求 while True:conn_socket, ip_port = tcp_server_socket.accept() 獲取瀏覽器發送的http請求報文數據client_request_data = conn_socket.recv(4096) 讀取固定頁面數據,把頁面數據組裝成HTTP響應報文數據發送給瀏覽器。response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body conn_socket.send(response_data) HTTP響應報文數據發送完成以后,關閉服務于客戶端的套接字。conn_socket.close()

靜態Web服務器-返回指定頁面數據

目前的Web服務器,不管用戶訪問什么頁面,返回的都是固定頁面的數據,接下來需要根據用戶的請求返回指定頁面的數據
返回指定頁面數據的實現步驟:
獲取用戶請求資源的路徑
根據請求資源的路徑,讀取指定文件的數據
組裝指定文件數據的響應報文,發送給瀏覽器
判斷請求的文件在服務端不存在,組裝404狀態的響應報文,發送給瀏覽器
靜態Web服務器-返回指定頁面數據的示例代碼

import socketdef 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(("", 9000))# 設置監聽tcp_server_socket.listen(128)while True:# 等待接受客戶端的連接請求new_socket, ip_port = tcp_server_socket.accept()# 代碼執行到此,說明連接建立成功recv_client_data = new_socket.recv(4096)if len(recv_client_data) == 0:print("關閉瀏覽器了")new_socket.close()return# 對二進制數據進行解碼recv_client_content = recv_client_data.decode("utf-8")print(recv_client_content)# 根據指定字符串進行分割, 最大分割次數指定2request_list = recv_client_content.split(" ", maxsplit=2)# 獲取請求資源路徑request_path = request_list[1]print(request_path)# 判斷請求的是否是根目錄,如果條件成立,指定首頁數據返回if request_path == "/":request_path = "/index.html"try:# 動態打開指定文件with open("static" + request_path, "rb") as file:# 讀取文件數據file_data = file.read()except Exception as e:# 請求資源不存在,返回404數據# 響應行response_line = "HTTP/1.1 404 Not Found\r\n"# 響應頭response_header = "Server: PWS1.0\r\n"with open("static/error.html", "rb") as file:file_data = file.read()# 響應體response_body = file_data# 拼接響應報文response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body# 發送數據new_socket.send(response_data)else:# 響應行response_line = "HTTP/1.1 200 OK\r\n"# 響應頭response_header = "Server: PWS1.0\r\n"# 響應體response_body = file_data# 拼接響應報文response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body# 發送數據new_socket.send(response_data)finally:# 關閉服務與客戶端的套接字new_socket.close()if __name__ == '__main__':main()

獲取用戶請求資源的路徑
request_list = client_request_conent.split(” ”, maxsplit=2)
request_path = request_list[1]
根據請求資源的路徑,讀取請求指定文件的數據
with open(“static” + request_path, “rb”) as file:
file_data = file.read()
組裝指定文件數據的響應報文,發送給瀏覽器
response_data = (response_line + response_header + “\r\n”).encode(“utf-8”) + response_body
conn_socket.send(response_data)
判斷請求的文件在服務端不存在,組裝404狀態的響應報文,發送給瀏覽器
try:
# 打開指定文件,代碼省略…
except Exception as e:
conn_socket.send(404響應報文數據)

靜態Web服務器-多任務版

靜態Web服務器的問題
目前的Web服務器,不能支持多用戶同時訪問,只能一個一個的處理客戶端的請求,那么如何開發多任務版的web服務器同時處理 多個客戶端的請求?
可以使用多線程,比進程更加節省內存資源。
多任務版web服務器程序的實現步驟:
當客戶端和服務端建立連接成功,創建子線程,使用子線程專門處理客戶端的請求,防止主線程阻塞。
把創建的子線程設置成為守護主線程,防止主線程無法退出。
靜態Web服務器-多任務版的示例代碼

import socket import threading# 處理客戶端的請求 def handle_client_request(new_socket):# 代碼執行到此,說明連接建立成功recv_client_data = new_socket.recv(4096)if len(recv_client_data) == 0:print("關閉瀏覽器了")new_socket.close()return# 對二進制數據進行解碼recv_client_content = recv_client_data.decode("utf-8")print(recv_client_content)# 根據指定字符串進行分割, 最大分割次數指定2request_list = recv_client_content.split(" ", maxsplit=2)# 獲取請求資源路徑request_path = request_list[1]print(request_path)# 判斷請求的是否是根目錄,如果條件成立,指定首頁數據返回if request_path == "/":request_path = "/index.html"try:# 動態打開指定文件with open("static" + request_path, "rb") as file:# 讀取文件數據file_data = file.read()except Exception as e:# 請求資源不存在,返回404數據# 響應行response_line = "HTTP/1.1 404 Not Found\r\n"# 響應頭response_header = "Server: PWS1.0\r\n"with open("static/error.html", "rb") as file:file_data = file.read()# 響應體response_body = file_data# 拼接響應報文response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body# 發送數據new_socket.send(response_data)else:# 響應行response_line = "HTTP/1.1 200 OK\r\n"# 響應頭response_header = "Server: PWS1.0\r\n"# 響應體response_body = file_data# 拼接響應報文response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body# 發送數據new_socket.send(response_data)finally:# 關閉服務與客戶端的套接字new_socket.close()# 程序入口函數 def 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(("", 9000))# 設置監聽tcp_server_socket.listen(128)while True:# 等待接受客戶端的連接請求new_socket, ip_port = tcp_server_socket.accept()print(ip_port)# 當客戶端和服務器建立連接程,創建子線程sub_thread = threading.Thread(target=handle_client_request, args=(new_socket,))# 設置守護主線程sub_thread.setDaemon(True)# 啟動子線程執行對應的任務sub_thread.start()if __name__ == '__main__':main()

當客戶端和服務端建立連接成功,創建子線程,使用子線程專門處理客戶端的請求,防止主線程阻塞。
while True:
conn_socket, ip_port = tcp_server_socket.accept()
# 開辟子線程并執行對應的任務
sub_thread = threading.Thread(target=handle_client_request, args=(conn_socket,))
把創建的子線程設置成為守護主線程,防止主線程無法退出。
開辟子線程并執行對應的任務
sub_thread = threading.Thread(target=handle_client_request, args=(conn_socket,))
sub_thread.setDaemon(True) # 設置守護主線程
sub_thread.start()

靜態Web服務器-面向對象開發

以面向對象的方式開發靜態Web服務器
實現步驟:
把提供服務的Web服務器抽象成一個類(HTTPWebServer)
提供Web服務器的初始化方法,在初始化方法里面創建socket對象
提供一個開啟Web服務器的方法,讓Web服務器處理客戶端請求操作。

靜態Web服務器-面向對象開發的示例代碼

import socket import threading# 定義web服務器類 class HttpWebServer(object):def __init__(self):# 創建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(("", 9000))# 設置監聽tcp_server_socket.listen(128)# 保存創建成功的服務器套接字self.tcp_server_socket = tcp_server_socket# 處理客戶端的請求@staticmethoddef handle_client_request(new_socket):# 代碼執行到此,說明連接建立成功recv_client_data = new_socket.recv(4096)if len(recv_client_data) == 0:print("關閉瀏覽器了")new_socket.close()return# 對二進制數據進行解碼recv_client_content = recv_client_data.decode("utf-8")print(recv_client_content)# 根據指定字符串進行分割, 最大分割次數指定2request_list = recv_client_content.split(" ", maxsplit=2)# 獲取請求資源路徑request_path = request_list[1]print(request_path)# 判斷請求的是否是根目錄,如果條件成立,指定首頁數據返回if request_path == "/":request_path = "/index.html"try:# 動態打開指定文件with open("static" + request_path, "rb") as file:# 讀取文件數據file_data = file.read()except Exception as e:# 請求資源不存在,返回404數據# 響應行response_line = "HTTP/1.1 404 Not Found\r\n"# 響應頭response_header = "Server: PWS1.0\r\n"with open("static/error.html", "rb") as file:file_data = file.read()# 響應體response_body = file_data# 拼接響應報文response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body# 發送數據new_socket.send(response_data)else:# 響應行response_line = "HTTP/1.1 200 OK\r\n"# 響應頭response_header = "Server: PWS1.0\r\n"# 響應體response_body = file_data# 拼接響應報文response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body# 發送數據new_socket.send(response_data)finally:# 關閉服務與客戶端的套接字new_socket.close()# 啟動web服務器進行工作def start(self):while True:# 等待接受客戶端的連接請求new_socket, ip_port = self.tcp_server_socket.accept()# 當客戶端和服務器建立連接程,創建子線程sub_thread = threading.Thread(target=self.handle_client_request, args=(new_socket,))# 設置守護主線程sub_thread.setDaemon(True)# 啟動子線程執行對應的任務sub_thread.start()# 程序入口函數 def main():# 創建web服務器對象web_server = HttpWebServer()# 啟動web服務器進行工作web_server.start()if __name__ == '__main__':main()

把提供服務的Web服務器抽象成一個類(HTTPWebServer)
class HttpWebServer(object):
提供Web服務器的初始化方法,在初始化方法里面創建socket對象
def init(self):
#初始化服務端套接字,設置監聽,代碼省略…
提供一個開啟Web服務器的方法,讓Web服務器處理客戶端請求操作。
def start(self):
while True:
service_client_socket, ip_port = self.tcp_server_socket.accept()
# 連接建立成功,開辟子線程處理客戶端的請求
sub_thread = threading.Thread(target=self.handle_client_request, args=(service_client_socket,))
sub_thread.start()

靜態Web服務器-命令行啟動動態綁定端口號

開發命令行啟動動態綁定端口號的靜態web服務器
實現步驟:
獲取執行python程序的終端命令行參數
判斷參數的類型,設置端口號必須是整型
給Web服務器類的初始化方法添加一個端口號參數,用于綁定端口號
靜態Web服務器-命令行啟動動態綁定端口號的示例代碼

import socket import threading import sys# 定義web服務器類 class HttpWebServer(object):def __init__(self, port):# 創建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(("", port))# 設置監聽tcp_server_socket.listen(128)# 保存創建成功的服務器套接字self.tcp_server_socket = tcp_server_socket# 處理客戶端的請求@staticmethoddef handle_client_request(new_socket):# 代碼執行到此,說明連接建立成功recv_client_data = new_socket.recv(4096)if len(recv_client_data) == 0:print("關閉瀏覽器了")new_socket.close()return# 對二進制數據進行解碼recv_client_content = recv_client_data.decode("utf-8")print(recv_client_content)# 根據指定字符串進行分割, 最大分割次數指定2request_list = recv_client_content.split(" ", maxsplit=2)# 獲取請求資源路徑request_path = request_list[1]print(request_path)# 判斷請求的是否是根目錄,如果條件成立,指定首頁數據返回if request_path == "/":request_path = "/index.html"try:# 動態打開指定文件with open("static" + request_path, "rb") as file:# 讀取文件數據file_data = file.read()except Exception as e:# 請求資源不存在,返回404數據# 響應行response_line = "HTTP/1.1 404 Not Found\r\n"# 響應頭response_header = "Server: PWS1.0\r\n"with open("static/error.html", "rb") as file:file_data = file.read()# 響應體response_body = file_data# 拼接響應報文response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body# 發送數據new_socket.send(response_data)else:# 響應行response_line = "HTTP/1.1 200 OK\r\n"# 響應頭response_header = "Server: PWS1.0\r\n"# 響應體response_body = file_data# 拼接響應報文response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body# 發送數據new_socket.send(response_data)finally:# 關閉服務與客戶端的套接字new_socket.close()# 啟動web服務器進行工作def start(self):while True:# 等待接受客戶端的連接請求new_socket, ip_port = self.tcp_server_socket.accept()# 當客戶端和服務器建立連接程,創建子線程sub_thread = threading.Thread(target=self.handle_client_request, args=(new_socket,))# 設置守護主線程sub_thread.setDaemon(True)# 啟動子線程執行對應的任務sub_thread.start()# 程序入口函數 def main():print(sys.argv)# 判斷命令行參數是否等于2,if len(sys.argv) != 2:print("執行命令如下: python3 xxx.py 8000")return# 判斷字符串是否都是數字組成if not sys.argv[1].isdigit():print("執行命令如下: python3 xxx.py 8000")return# 獲取終端命令行參數port = int(sys.argv[1])# 創建web服務器對象web_server = HttpWebServer(port)# 啟動web服務器進行工作web_server.start()if __name__ == '__main__':main()

獲取執行python程序的終端命令行參數
sys.argv
判斷參數的類型,設置端口號必須是整型
if not sys.argv[1].isdigit():
print(“啟動命令如下: python3 xxx.py 9090”)
return
port = int(sys.argv[1])
給Web服務器類的初始化方法添加一個端口號參數,用于綁定端口號
def init(self, port):
self.tcp_server_socket.bind((“”, port))

總結

以上是生活随笔為你收集整理的网络编程学习的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。