1. 程式人生 > >python網路程式設計-udp

python網路程式設計-udp

目錄

1. 建立socket

在 Python 中 使用socket 模組的函式 socket 就可以完成(大多數的程式語言的套路是相似的):

import socket
socket.socket(AddressFamily, Type)

說明:

函式 socket.socket 建立一個 socket,該函式帶有兩個引數:

  • Address Family:可以選擇 AF_INET(用於 Internet 程序間通訊) 或者 AF_UNIX(用於同一臺機器程序間通訊),實際工作中常用AF_INET
  • Type:套接字型別,可以是 SOCK_STREAM(流式套接字,主要用於 TCP 協議)或者 SOCK_DGRAM(資料報套接字,主要用於 UDP 協議)

建立一個udp socket(udp套接字):

import socket

# 建立udp socket
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# ...
# 使用套接字收/發資料

# 關閉socket
udp_socket.close()

說明:

  • 套接字使用流程 與 檔案的使用流程很類似
    1. 建立套接字
    2. 使用套接字收/發資料
    3. 關閉套接字

2. udp網路程式-傳送資料

建立一個基於udp的網路程式流程很簡單,具體步驟如下:

  1. 建立客戶端套接字
  2. 傳送/接收資料
  3. 關閉套接字
import socket

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

        # 讀取輸入的資料
        send_data = input('請輸入要傳送的資料:')

        # 傳送資料
        send_addr = ('192.168.92.190', 7878)
        udp_socket.sendto(send_data.encode('GBK'), send_addr)

        # 關閉
        udp_socket.close()



if __name__ == '__main__':
        main()

在ubuntu的終端中執行:

在windows中執行“網路除錯助手”:

3. udp網路程式-接收資料

import socket

def main():

        # 建立套接字
        udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

        # 繫結一個本地資訊
        localaddr = ("", 8080)
        udp_socket.bind(localaddr)

        # 接收資料
        recv_data = udp_socket.recvfrom(1024)

        # recv_data是一個元組(接收到的資料, (傳送方的IP, port))
        recv_msg = recv_data[0] # 儲存接收到的資料
        send_addr = recv_data[1] # 儲存傳送方的地址

        # 列印收到的訊息
        # print(recv_data)
        print("%s:%s" % (str(send_addr), recv_msg.decode('GBK')))

        # 關閉
        udp_socket.close()

if __name__ == '__main__':
        main()
        

在ubuntu的終端中執行:

在網咯助手中傳送資料:

4. python3中的編碼轉換

  • 使用socket傳送的是資料的二進位制,需要將字串轉換成bytes
str.encode()
  • 使用socket接收的是資料的二進位制,需要將bytes轉換成字元
bytes.decode()

在ipython3中嘗試:

In [2]: text = "一串文字"

In [3]: text
Out[3]: '一串文字'

In [5]: bytes_text = text.encode()

In [6]: bytes_text
Out[6]: b'\xe4\xb8\x80\xe4\xb8\xb2\xe6\x96\x87\xe6\x9c\xac'

In [7]: type(text)
Out[7]: str

In [8]: type(bytes_text)
Out[8]: bytes

In [9]: decoded_text = bytes_text.decode()
    
In [10]: decoded_text
Out[10]: '一串文字'

其中decode()與encode()方法可以接受引數,其宣告分別為:

bytes.decode(encoding="utf-8", errors="strict")
str.encode(encoding="utf-8", errors="strict")

其中的encoding是指在解碼編碼過程中使用的編碼(此處指“編碼方案”是名詞),errors是指錯誤的處理方案。

詳細的可以參照官方文件:

5. udp埠繫結

  • 一個udp網路程式,執行時沒有繫結埠,系統會給它分配一個隨機的埠,如果再次執行,埠可能發生變化
  • 一個udp網路程式,也可以繫結資訊(ip地址,埠號),如果繫結成功,那麼作業系統用這個埠號來進行區別收到的網路資料是否是此程序的

什麼時候需要繫結埠呢?

一般來說,如果要做成一個服務端的應用程式的話,是需要繫結固定埠的。