python網路程式設計 TCP協議 TCP與UDP的區別
阿新 • • 發佈:2018-12-12
TCP(Transmission Control Protocol)簡稱傳輸控制協議,它是一種面向連線的、可靠的、基於位元組流的傳輸層通訊協議。
建立TCP通訊三個步驟:
- 建立連線
- 資料傳送
- 終止連線
TCP通訊類似於生活中的打電話,通訊開始前一定要先建立相關的連線。
TCP特點:
- 面向連線 這種連線是一對一的,因此TCP不適用於廣播的應用程式
- 可靠傳輸
- TCP採用應答機制
- 超時重傳
- 錯誤校驗
- 流量控制和阻塞管理
TCP優點:
- 可靠、穩定
- 適合傳輸大量資料
TCP缺點:
- 傳輸速度慢
- 佔用系統資源高
TCP的使用場景:對網路通訊質量有較高要求
- 瀏覽器 HTTP協議基於TCP協議
- 檔案傳輸
TCP的三次握手(連線)
TCP的4次揮手(斷開)
TCP網路程式流程
案例 基於TCP的檔案下載器(同步下載)
TCP嚴格區分客戶端與服務端。
TCP客戶端
import socket if __name__ == '__main__': # 建立tcp客戶端套接字 tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 和服務端程式建立連線 tcp_client_socket.connect(("127.0.0.1", 8989)) # 接收使用者下載的檔名資料 file_name = input("請輸入您要下載的檔名:") # 對字串程序編碼成為二進位制資料 file_name_data = file_name.encode("utf-8") # 傳送資料 tcp_client_socket.send(file_name_data) # 指定路徑,先把檔案建立到指定路徑,然後在開啟檔案寫入資料 with open("/home/python/Desktop/" + file_name, "wb") as file: # 迴圈接收服務端傳送的檔案二進位制資料 while True: # 接收一次服務端傳送的資料 file_data = tcp_client_socket.recv(1024) if file_data: # 迴圈往檔案中寫入資料 file.write(file_data) else: # 服務端傳送檔案完成 break # 關閉套接字 tcp_client_socket.close()
TCP服務端
import socket import os if __name__ == '__main__': tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 設定socket選項,程式退出埠號立即釋放, 可以複用埠號 # 提示: 預設是 tcp斷開連線,但真正釋放埠號需要等待1-2分鐘 tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,True) # 給程式繫結埠號 tcp_server_socket.bind(("", 8989)) # 設定監聽 tcp_server_socket.listen(128) # 迴圈等待接收客戶端的連線請求,可以服務與多個客戶端, 但是是一個客戶端下載檔案以後另外一個客戶端才能下載檔案 while True: # 等待接收客戶端的連線請求 service_client_socket, ip_port = tcp_server_socket.accept() # 程式碼執行到此,說明連線建立成功 print("客戶端的ip地址和埠號:", ip_port) # 接收客戶端請求資料(其實就是客戶端傳送的檔名) recv_data = service_client_socket.recv(1024) # 對二進位制資料進行解碼 file_name = recv_data.decode("utf-8") print(file_name) # 判斷請求的檔案是否存在 # 1. try-except 如果開啟檔案出現異常,說明檔案不存在 # 2. os.path.exits 判斷檔案是否存在 # 判斷指定檔案或者資料夾是否存在 if os.path.exists(file_name): # 根據客戶端請求檔名開啟指定檔案,讀取檔案中的資料 with open(file_name, "rb") as file: while True: # 讀取檔案資料 file_data = file.read(1024) if file_data: # 傳送資料給客戶端 service_client_socket.send(file_data) else: # 檔案讀取完成 break else: service_client_socket.send("無此檔案".encode("utf-8") service_client_socket.close() # tcp_server_socket.close()
TCP注意點:
- tcp伺服器一般情況下都需要繫結埠號,否則客戶端找不到這個伺服器
- tcp客戶端一般不繫結埠號,使用隨機生成的埠號即可
- 當一個tcp客戶端和服務端連線成功後,伺服器端會有1個新的套接字,這個套接字用來標記這個客戶端,單獨為這個客戶端服務
- listen後的套接字是被動套接字,只用來接收新的客戶端的連結請求的,而accept返回的新套接字是標記這個新客戶端的
- 關閉listen後的套接字意味著被動套接字關閉了,會導致新的客戶端不能夠連線伺服器,但是之前已經連線成功的客戶端正常通訊
- 關閉accept返回的套接字意味著這個客戶端已經服務完畢,注意和第5點的區別
- 當客戶端的套接字呼叫close後,伺服器端會recv解堵塞,並且返回的長度為0,因此伺服器可以通過返回資料的長度來區別客戶端是否已經下線
2.TCP和UDP的區別
- TCP面向連線,UDP不面向連線
- TCP需要連線 傳輸速度慢,UDP不需要連線 傳輸速度快
- TCP不支援發廣播,UDP支援發廣播
- TCP對系統資源要求較多,UDP對系統資源要求較少
- TCP提供可靠的資料傳輸,UDP不保證可靠的資料傳輸,易出現丟包情況
- TCP適合傳送大量資料,UDP適合傳送少量資料
- TCP有流量控制,UDP沒有流量控制