1. 程式人生 > >python的網路通訊 :UDP以及TCP

python的網路通訊 :UDP以及TCP

一般的網路t通訊就是,讓在網路中不同的電腦上的軟體能夠進行資料傳遞,即網路中不同主機程序之間的通訊!

而python裡實現網路通訊是有UDP和TCP兩種實現方式!

UDP 協議:是一種無狀態的連線方式,它是一種報文型的連線,也就是它只會把資料傳送過去,但是對於資料是否正確傳送到達,並且對於在傳送過程中出現的各種問題,它都不會關心!它的特點就是快!

udp傳輸程式碼實現的流程圖


以下實現udp的程式碼段,udp沒有伺服器與瀏覽器之分,是根據指定的ip與埠之分,

import socket


def main():
    # . 建立udp socket套接字物件
    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)


    send_data = input("請輸入要傳送的資料:")


    dest_addr = ("ip地址", 6666)  
    udp_socket.sendto(send_data.encode("utf-8"), dest_addr) 



    recv_data = udp_socket.recvfrom(1024)  


    recv_info = recv_data[0]  # bytes-->string :解碼
    recv_ip = str(recv_data[1])
    print("接收到的資訊是%s, 來自>>>%s" % (recv_info, recv_ip))


    #  關閉socket
    udp_socket.close()


if __name__ == '__main__':
    main()

TCP協議:也叫傳輸控制協議,它是一種面向連線的位元組流傳輸協議!它有幾大特性:

    1.在建立連線之前會有三次握手,結束連線時有四次揮手!三次握手即:瀏覽器會先發送一個數據包請求給伺服器,然後伺服器接到資料包後會根據預定的演算法做一定的處理,然後把資料包傳送回瀏覽器,並且同時也傳送一個請求連線的資料包,瀏覽器接收到資料包後會先對上一次傳送的請求資料包進行效驗,當確認無誤後在對伺服器傳送的請求資料包進行處理然後返回給伺服器,最後伺服器接受到資料包並效驗無誤後就會正式建立連線進行正式資料的傳輸!這個過程的目的其實是為了確認瀏覽器與伺服器雙方是否都能正確無誤的收發資料!

四次揮手:即在當Tcp連線的雙方任何一方想要結束連線時都會有一個確認關閉連線的過程,(關閉連線請求瀏覽器與伺服器都可以傳送!)即想要關閉連線的一方向另一方傳送一個連線請求,如果說另一方正在給這邊傳送資料的話,它會等到所有要傳送的資料完整的傳送完,在給這邊傳送給一個可以關閉連線的應答,而想要中斷連線的那一邊傳送結束連線後在進入一個w'ait的等待狀態,知道另一方給這邊傳送可以結束連線的響應後它會再給被動結束的那一方再發一個得到響應的應答,而被動結束連線的那一邊接受到主動連線的應答後,才會給一個應答後率先關閉連線,最後請求關閉連線那一端才會關閉連線!這次四次握手的那麼墨跡的過程,只要作用時為了確保中斷的時候的正在傳送的資料能正常到達,避免造成資料的損失,我覺得是對傳輸過程傳送資料的完整型的一種負責體現吧!


2.Tcp協議還有其他可靠傳輸的機制:

(1)TCP採用傳送應答機制


TCP傳送的每個報文段都必須得到接收方的應答才認為這個TCP報文段傳輸成功


(2)超時重傳


傳送端發出一個報文段之後就啟動定時器,如果在定時時間內沒有收到應答就重新發送這個報文段。


TCP為了保證不發生丟包,就給每個包一個序號,同時序號也保證了傳送到接收端實體的包的按序接收。然後接收端實體對已成功收到的包發回一個相應的確認(ACK);如果傳送端實體在合理的往返時延(RTT)內未收到確認,那麼對應的資料包就被假設為已丟失將會被進行重傳。


(3)錯誤校驗


TCP用一個校驗和函式來檢驗資料是否有錯誤;在傳送和接收時都要計算校驗和。


(4) 流量控制和阻塞管理


流量控制用來避免主機發送得過快而使接收方來不及完全收下。

以下時tcp的程式碼實現流程圖


實現tcp的程式碼段,TCP有服務端與客戶端之分,在服務端上必須繫結ip以及埠,並且進行監聽:

#以下為python實現tcp協議服務端的程式碼段
import socket
def tcp_server():
    # 1. 建立服務端的socket物件,用來監聽客戶端的請求
    tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # 2. 繫結ip埠
    tcp_server_socket.bind(("這裡是ip地址", 6666))

    # 3. server_socket 開啟監聽,由主動模式變為被動監聽模式
    tcp_server_socket.listen()
    print("服務端已經監聽客戶端的請求")
    # 4. 等待接收客戶端的請求
    # new_client_sock: 為請求的客戶端單獨建立一個socket物件,實現與客戶端的通訊
    # client_addr :客戶端的地址
    new_client_sock, client_addr = tcp_server_socket.accept()
    print("接收到來自%s 的請求" % str(client_addr))
    # 5. 接收由客戶端傳送過來的資料
    recv_data = new_client_sock.recv(1024)
    print("接收到客戶端的資料:", recv_data)
    # 6. 傳送資料給客戶端
    new_client_sock.send("啦啦啦,我是可愛的服務端!".encode("utf-8"))
    # 7. 關閉與客戶端對接的socket物件,不再與當前客戶端通訊
    new_client_sock.close()
    # 8. 關閉server_socket, 不再接收新的客戶端請求
    tcp_server_socket.close()
#--------------------------------------------------------------------------
#這是一個實現tcp客戶端的簡單的程式碼段
def tcp_cli():
    # 1. 建立tcp socket物件
    tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 2. 客戶端需要指定埠地址,就像我們瀏覽器訪問網頁需要輸入一個域名
    server_ip = input("服務端的ip:")
    server_port = input("服務端的埠號:")
    tcp_client_socket.connect((server_ip, int(server_port)))
    # 3. 傳送資料給服務端
    send_data = input("啦啦啦!我是威猛的客戶端!:")
    tcp_client_socket.send(send_data.encode("utf-8")) 
    # 4. 等待接收 服務端回傳的資料
    # recv_data=tcp_client_socket.recvfrom(1024) 
    recv_data = tcp_client_socket.recv(1024)  
    print("收到的資料:",recv_data)
  
    # 5. 關閉連線,關閉socket
    tcp_client_socket.close()