1. 程式人生 > >python網路程式設計 TCP協議 TCP與UDP的區別

python網路程式設計 TCP協議 TCP與UDP的區別

TCP(Transmission Control Protocol)簡稱傳輸控制協議,它是一種面向連線的、可靠的、基於位元組流的傳輸層通訊協議。

建立TCP通訊三個步驟:

  1. 建立連線
  2. 資料傳送
  3. 終止連線

TCP通訊類似於生活中的打電話,通訊開始前一定要先建立相關的連線。

TCP特點:

  1. 面向連線  這種連線是一對一的,因此TCP不適用於廣播的應用程式
  2. 可靠傳輸
    1. TCP採用應答機制
    2. 超時重傳
    3. 錯誤校驗
    4. 流量控制和阻塞管理

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注意點:

  1. tcp伺服器一般情況下都需要繫結埠號,否則客戶端找不到這個伺服器
  2. tcp客戶端一般不繫結埠號,使用隨機生成的埠號即可
  3. 當一個tcp客戶端和服務端連線成功後,伺服器端會有1個新的套接字,這個套接字用來標記這個客戶端,單獨為這個客戶端服務
  4. listen後的套接字是被動套接字,只用來接收新的客戶端的連結請求的,而accept返回的新套接字是標記這個新客戶端的
  5. 關閉listen後的套接字意味著被動套接字關閉了,會導致新的客戶端不能夠連線伺服器,但是之前已經連線成功的客戶端正常通訊
  6. 關閉accept返回的套接字意味著這個客戶端已經服務完畢,注意和第5點的區別
  7. 當客戶端的套接字呼叫close後,伺服器端會recv解堵塞,並且返回的長度為0,因此伺服器可以通過返回資料的長度來區別客戶端是否已經下線

2.TCP和UDP的區別

  1. TCP面向連線,UDP不面向連線
  2. TCP需要連線 傳輸速度慢,UDP不需要連線 傳輸速度快
  3. TCP不支援發廣播,UDP支援發廣播
  4. TCP對系統資源要求較多,UDP對系統資源要求較少
  5. TCP提供可靠的資料傳輸,UDP不保證可靠的資料傳輸,易出現丟包情況
  6. TCP適合傳送大量資料,UDP適合傳送少量資料
  7. TCP有流量控制,UDP沒有流量控制