1. 如何強行關閉客戶端和服務器之間的連接?
在網絡編程中,有時需要強行中斷客戶端和服務器之間的連接。對于基于 TCP 協議的連接,由于其面向連接的特性,需要采取特定的步驟來確保連接被正確關閉;而 UDP 是無連接協議,處理方式相對簡單。
服務器端(TCP)
python
import socket# 創建 TCP 套接字
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 綁定地址和端口
server_socket.bind(('localhost', 8888))
# 開始監聽
server_socket.listen(1)print("Waiting for a connection...")
# 接受客戶端連接
conn, addr = server_socket.accept()
print(f"Connected by {addr}")try:# 強制關閉連接# 先禁用讀寫conn.shutdown(socket.SHUT_RDWR)# 關閉連接conn.close()print("Connection closed.")
except Exception as e:print(f"Error closing connection: {e}")
客戶端(TCP)
python
import socket# 創建 TCP 套接字
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 連接到服務器
client_socket.connect(('localhost', 8888))try:# 強制關閉連接client_socket.shutdown(socket.SHUT_RDWR)client_socket.close()print("Connection closed.")
except Exception as e:print(f"Error closing connection: {e}")
服務器端(UDP)
python
import socket# 創建 UDP 套接字
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 綁定地址和端口
server_socket.bind(('localhost', 8888))try:# 停止接收數據并關閉套接字server_socket.close()print("UDP socket closed.")
except Exception as e:print(f"Error closing UDP socket: {e}")
- 要點
- TCP 連接關閉需要先使用
shutdown
方法禁用讀寫,再調用close
方法關閉連接。 - UDP 連接直接調用
close
方法關閉套接字。 - 在實際應用中,強行關閉連接可能會導致數據丟失或未完成的操作中斷。因此,在關閉連接之前,最好確保所有必要的數據已經傳輸完成。另外,對于 TCP 連接,
shutdown
方法可以指定不同的參數,如socket.SHUT_RD
表示關閉讀通道,socket.SHUT_WR
表示關閉寫通道。
2. 說明 TCP 和 UDP 的區別以及優缺點
TCP(Transmission Control Protocol)和 UDP(User Datagram Protocol)是兩種常見的傳輸層協議,它們在連接性、可靠性、有序性、傳輸效率和首部開銷等方面存在明顯差異。
python
import socket# TCP 服務器示例
def tcp_server():server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)server_socket.bind(('localhost', 8888))server_socket.listen(1)print("TCP server is listening...")conn, addr = server_socket.accept()data = conn.recv(1024)print(f"Received from {addr}: {data.decode()}")conn.close()# UDP 服務器示例
def udp_server():server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)server_socket.bind(('localhost', 8889))print("UDP server is listening...")data, addr = server_socket.recvfrom(1024)print(f"Received from {addr}: {data.decode()}")server_socket.close()if __name__ == "__main__":import threadingtcp_thread = threading.Thread(target=tcp_server)udp_thread = threading.Thread(target=udp_server)tcp_thread.start()udp_thread.start()
- 要點
對比項 | TCP | UDP |
---|---|---|
連接性 | 面向連接,需三次握手建立連接,四次揮手斷開連接 | 無連接,直接發送數據 |
可靠性 | 提供可靠傳輸,有確認、重傳、滑動窗口機制 | 不可靠,可能丟包、亂序 |
有序性 | 保證數據有序接收 | 不保證數據有序 |
傳輸效率 | 相對較低,有連接建立和斷開開銷 | 相對較高,無連接開銷 |
首部開銷 | 一般為 20 字節 | 固定為 8 字節 |
優點 | 可靠、有序,適用于文件傳輸、網頁瀏覽 | 高效、開銷小,適用于實時性要求高的場景 |
缺點 | 效率低、資源占用多 | 不可靠、不保證有序 |
在選擇使用 TCP 還是 UDP 時,需要根據具體的應用場景來決定。例如,對于視頻會議、在線游戲等對實時性要求較高的應用,即使可能會有少量數據丟失,也更適合使用 UDP;而對于文件下載、電子郵件等對數據準確性要求較高的應用,則應選擇 TCP。
3. 簡述瀏覽器通過 WSGI 請求動態資源的過程
WSGI(Web Server Gateway Interface)是 Python Web 應用程序和 Web 服務器之間的標準接口,它定義了 Web 服務器如何與 Python 應用程序進行通信。瀏覽器通過 WSGI 請求動態資源的過程涉及多個環節。
python
def simple_app(environ, start_response):"""簡單的 WSGI 應用"""status = '200 OK'headers = [('Content-type', 'text/plain; charset=utf-8')]start_response(status, headers)return [b'Hello, World!']if __name__ == '__main__':from wsgiref.simple_server import make_serverhttpd = make_server('localhost', 8000, simple_app)print("Serving on port 8000...")httpd.serve_forever()
- 要點
-
瀏覽器發起 HTTP 請求。
-
Web 服務器(如 Apache、Nginx)接收請求。
-
Web 服務器將請求信息封裝成符合 WSGI 規范的環境變量和可調用對象,調用 WSGI 應用程序。
-
WSGI 應用程序處理請求,可能訪問數據庫、調用其他服務。
-
WSGI 應用程序返回響應信息。
-
Web 服務器將響應信息封裝成 HTTP 響應,發送給瀏覽器。
-
瀏覽器解析渲染頁面。
WSGI 使得 Python Web 應用程序可以在不同的 Web 服務器上運行,提高了代碼的可移植性。常見的 Python Web 框架如 Flask、Django 都遵循 WSGI 規范。
4. 說明瀏覽器訪問 www.baidu.com 的過程
當用戶在瀏覽器中輸入 www.baidu.com
并回車后,瀏覽器會經歷一系列步驟來獲取并顯示百度的網頁。
python
import sockettry:ip = socket.gethostbyname('www.baidu.com')print(f"The IP address of www.baidu.com is {ip}")
except socket.gaierror as e:print(f"DNS resolution error: {e}")
- 要點
-
DNS 解析:瀏覽器先檢查本地 DNS 緩存,若沒有則向本地 DNS 服務器查詢,本地 DNS 服務器若沒有則逐級向根 DNS 服務器、頂級域名 DNS 服務器、權威 DNS 服務器查詢,最終獲取目標網站的 IP 地址。
-
TCP 連接:使用獲取到的 IP 地址和端口號(通常是 80 或 443),通過三次握手與服務器建立 TCP 連接。
-
HTTP 請求:瀏覽器向服務器發送 HTTP 請求,包含請求方法、URL、請求頭和請求體。
-
服務器處理請求:服務器根據請求內容進行處理,可能涉及數據庫查詢、應用程序調用等。
-
HTTP 響應:服務器處理完請求后,向瀏覽器發送 HTTP 響應,包含響應狀態碼、響應頭和響應體。
-
瀏覽器解析渲染頁面:瀏覽器解析響應內容,構建 DOM 樹、CSSOM 樹,合并成渲染樹,進行布局和繪制。
-
TCP 連接關閉:頁面渲染完成后,通過四次揮手關閉 TCP 連接。
在實際過程中,還可能涉及到 HTTPS 協議的加密和解密過程,以及緩存策略的應用,以提高訪問速度和性能。
5. 說明Post 和 Get 請求的區別
Post 和 Get 是 HTTP 協議中常用的兩種請求方法,它們在參數傳遞方式、安全性、數據長度限制、緩存和使用場景等方面存在差異。
python
import requests# Get 請求示例
response_get = requests.get('https://www.example.com', params={'key': 'value'})
print(f"Get response status code: {response_get.status_code}")# Post 請求示例
data = {'key': 'value'}
response_post = requests.post('https://www.example.com', data=data)
print(f"Post response status code: {response_post.status_code}")
- 要點
對比項 | Get | Post |
---|---|---|
參數傳遞方式 | 參數附加在 URL 后面 | 參數放在請求體中 |
安全性 | 參數暴露在 URL 中,不安全 | 參數在請求體中,相對安全 |
數據長度限制 | URL 長度有限制 | 無數據長度限制 |
緩存 | 會被瀏覽器緩存 | 一般不會被緩存 |
使用場景 | 適用于獲取數據 | 適用于提交數據 |
在實際開發中,需要根據具體的需求選擇合適的請求方法。同時,對于敏感信息的傳遞,即使使用 Post 請求,也建議采用 HTTPS 協議進行加密傳輸。
6. 說明cookie 和 session 的區別
Cookie 和 Session 是 Web 開發中用于跟蹤用戶狀態的兩種機制,它們在存儲位置、安全性、數據大小、有效期和應用場景等方面有所不同。
python
from flask import Flask, request, make_response, sessionapp = Flask(__name__)
app.secret_key = 'your_secret_key'@app.route('/set_cookie')
def set_cookie():resp = make_response('Setting cookie...')resp.set_cookie('username', 'John')return resp@app.route('/get_cookie')
def get_cookie():username = request.cookies.get('username')return f'Cookie username: {username}'@app.route('/set_session')
def set_session():session['user'] = 'John'return 'Setting session...'@app.route('/get_session')
def get_session():user = session.get('user')return f'Session user: {user}'if __name__ == '__main__':app.run(debug=True)
- 要點
對比項 | Cookie | Session |
---|---|---|
存儲位置 | 客戶端瀏覽器 | 服務器端 |
安全性 | 不安全,可能被分析和欺騙 | 相對安全,數據在服務器端 |
數據大小 | 單個 Cookie 不超過 4K,一個站點最多保存 20 個 | 無數據大小限制 |
有效期 | 可通過 | 默認瀏覽器關閉失效,可設置延長 |
應用場景 | 保存基本信息,如用戶名、偏好設置 | 保存登錄狀態、購物車信息 |
在使用 Cookie 和 Session 時,需要注意安全性問題。對于 Cookie,可以設置 HttpOnly
和 Secure
屬性來提高安全性;對于 Session,需要對會話 ID 進行加密和管理,防止會話劫持。
7.? HTTP 協議有哪些狀態碼
HTTP 狀態碼是服務器返回給客戶端的三位數字代碼,用于表示請求的結果。常見的狀態碼可以分為五類。
python
import requestsresponse = requests.get('https://www.example.com')
print(f"Response status code: {response.status_code}")
- 要點
狀態碼分類 | 含義 | 常見狀態碼及說明 |
---|---|---|
1xx(信息性狀態碼) | 表示臨時響應,用于通知客戶端部分請求已被接收 | 100 Continue:客戶端應繼續發送請求 |
2xx(成功狀態碼) | 表示請求成功 | 200 OK:請求成功;201 Created:資源已創建;204 No Content:請求成功但無返回內容 |
3xx(重定向狀態碼) | 表示需要進一步操作以完成請求 | 301 Moved Permanently:資源永久移動;302 Found:資源臨時移動;304 Not Modified:資源未修改,可使用緩存 |
4xx(客戶端錯誤狀態碼) | 表示客戶端請求有錯誤 | 400 Bad Request:請求語法錯誤;401 Unauthorized:未授權;403 Forbidden:服務器拒絕執行;404 Not Found:資源不存在 |
5xx(服務器錯誤狀態碼) | 表示服務器處理請求時出現錯誤 | 500 Internal Server Error:服務器內部錯誤;502 Bad Gateway:網關或代理接收到無效響應;503 Service Unavailable:服務器臨時不可用 |
在實際開發中,根據不同的狀態碼可以進行相應的處理。例如,當返回 404 狀態碼時,可以顯示自定義的錯誤頁面;當返回 500 狀態碼時,需要記錄錯誤日志以便排查問題。
8. 什么是三次握手和四次揮手
三次握手是 TCP 建立連接的過程,確保雙方都有發送和接收數據的能力;四次揮手是 TCP 斷開連接的過程,確保雙方都能正確關閉連接。
python
# 模擬三次握手
def three_way_handshake():print("Client: SYN, seq=x")print("Server: SYN+ACK, seq=y, ack=x+1")print("Client: ACK, ack=y+1")print("Connection established.")# 模擬四次揮手
def four_way_wave():print("Client: FIN, seq=u")print("Server: ACK, ack=u+1")print("Server: FIN, seq=v")print("Client: ACK, ack=v+1")print("Connection closed.")if __name__ == "__main__":print("Three-way handshake:")three_way_handshake()print("\nFour-way wave:")four_way_wave()
- 要點
三次握手:
-
客戶端發送 SYN 包,請求建立連接。
-
服務器發送 SYN+ACK 包,同意建立連接并確認客戶端請求。
-
客戶端發送 ACK 包,確認服務器請求,連接建立。
四次揮手:
-
客戶端發送 FIN 包,請求關閉連接。
-
服務器發送 ACK 包,確認客戶端關閉請求。
-
服務器發送 FIN 包,請求關閉連接。
-
客戶端發送 ACK 包,確認服務器關閉請求,連接斷開。
三次握手和四次揮手是 TCP 協議保證連接可靠性的重要機制。在實際網絡環境中,可能會出現丟包、超時等情況,需要通過重傳機制來確保連接的正常建立和關閉。
9. 什么是 TCP 的 2MSL
MSL(Maximum Segment Lifetime)是指一個 TCP 分段在網絡中最大的生存時間。2MSL 即兩倍的 MSL 時間。在 TCP 連接關閉過程中,主動關閉連接的一方在發送最后一個 ACK 包后,會進入 TIME - WAIT 狀態并保持 2MSL 時間。
python
# 模擬 TCP 連接關閉進入 TIME - WAIT 狀態
def tcp_connection_close():print("Client sends FIN to close connection.")print("Server sends ACK.")print("Server sends FIN.")print("Client sends ACK and enters TIME - WAIT state for 2MSL.")if __name__ == "__main__":tcp_connection_close()
- 要點
-
MSL 是 TCP 分段在網絡中的最大生存時間。
-
2MSL 是主動關閉連接方在 TIME - WAIT 狀態的停留時間。
不同的操作系統對 MSL 的定義可能不同,一般來說,MSL 的值在 30 秒到 2 分鐘之間。2MSL 時間的設置是為了保證 TCP 連接的可靠
友情提示:本文已經整理成文檔,可以到如下鏈接免積分下載閱讀
https://download.csdn.net/download/ylfhpy/90411385