python網路-Socket之udp編程(24)

来源:https://www.cnblogs.com/Se7eN-HOU/archive/2019/04/20/10742148.html
-Advertisement-
Play Games

一、udp簡介 udp 用戶數據報協議,是一個無連接的簡單的面向數據報的運輸層協議。 udp不提供可靠性,它只是把應用程式傳給IP層的數據報發送出去,但是並不能保證它們能到達目的地。 udp在傳輸數據報前不用在客戶和伺服器之間建立一個連接,且沒有超時重發等機制,故而傳輸速度很快。 udp是一種面向無 ...


 

一、udp簡介

  • udp --- 用戶數據報協議,是一個無連接的簡單的面向數據報的運輸層協議。
  • udp不提供可靠性,它只是把應用程式傳給IP層的數據報發送出去,但是並不能保證它們能到達目的地。
  • udp在傳輸數據報前不用在客戶和伺服器之間建立一個連接,且沒有超時重發等機制,故而傳輸速度很快。
  • udp是一種面向無連接的協議,每個數據報都是一個獨立的信息,包括完整的源地址或目的地址,它在網路上以任何可能的路徑傳往目的地,因此能否到達目的地,到達目的地的時間以及內容的正確性都是不能被保證的。

 

二、udp特點:

udp是面向無連接的通訊協議,udp數據包括目的埠號和源埠號信息,由於通訊不需要連接,所以可以實現廣播發送。 udp傳輸數據時有大小限制,每個被傳輸的數據報必須限定在64KB之內。 udp是一個不可靠的協議,發送方所發送的數據報並不一定以相同的次序到達接收方。udp是面向消息的協議,通信時不需要建立連接,數據的傳輸自然是不可靠的,udp一般用於多點通信和實時的數據業務,比如:

  • 語音廣播
  • TFTP(簡單文件傳送)
  • SNMP(簡單網路管理協議)
  • RIP(路由信息協議,如報告股票市場,航空信息)
  • DNS(功能變數名稱解釋)

 

三、udp網路程式-發送數據

創建一個udp客戶端程式的流程是簡單,具體步驟如下:

  1. 創建客戶端套接字
  2. 發送/接收數據
  3. 關閉套接字

代碼如下:

#coding=utf-8
from socket import *

#1、創建socket套接字
#socket(參數1,參數2)
#參數1 = AF_INET固定的
#參數2 = SOCK_DGRAM表示udp,上篇文章中說過SOCK_STREM表示tcp
udpSocket = socket(AF_INET,SOCK_DGRAM)

#2、準備接收方的地址
sendAddress = ("192.168.100.101",8080)

#3、從鍵盤輸入需要發送的數據
sendData = input("請輸入要發送的數據:")

#4、發送數據到指定電腦
udpSocket.sendto(sendData.encode(),sendAddress)

#5、關閉socket套接字
udpSocket.close()

運行程式:

這個時候我就向我的另外一臺IP地址為:192.168.100.101 埠號為8080的程式發送了“我是侯哥”這一條消息。我們藉助於網路調試助手軟體用於測試,網路調試助手各個平臺的系統都有,大家可以自己下載使用。

說明:我的代碼是在windows電腦上運行的,我的網路調試助手是在Mac電腦上運行的,如果沒有兩臺電腦的,也可以使用虛擬機測試。

 

四、udp網路程式-接收數據

#coding=utf-8
from socket import *

#1、創建socket套接字
udpSocket = socket(AF_INET,SOCK_DGRAM)

#2、準備接收方的地址
sendAddress = ("192.168.100.101",8080)

#3、從鍵盤輸入需要發送的數據
sendData = input("請輸入要發送的數據:")

#4、發送數據到指定電腦
udpSocket.sendto(sendData.encode(),sendAddress)

#5、等待接收對方發送的數據
receiveData = udpSocket.recvfrom(1024)

#6、顯示對方發送的數據
print(receiveData)

#7、關閉socket套接字
udpSocket.close()

運行程式:

 

五、udp網路程式-埠問題

會變的埠號:重新運行多次腳本,然後在“網路調試助手”中,看到的現象如下:

說明:

  • 每重新運行一次網路程式,上圖中紅圈中的數字,不一樣的原因在於,這個數字標識這個網路程式,當重新運行時,如果沒有確定到底用哪個,系統預設會隨機分配
  • 記住一點:這個網路程式在運行的過程中,這個就唯一標識這個程式,所以如果其他電腦上的網路程式如果想要向此程式發送數據,那麼就需要向這個數字(即埠)標識的程式發送即可

 

六、udp綁定信息

一般情況下,在一天電腦上運行的網路程式有很多,而各自用的埠號很多情況下不知道,為了不與其他的網路程式占用同一個埠號,往往在編程中,udp的埠號一般不綁定,但是如果需要做成一個伺服器端的程式的話,是需要綁定的。就像報警電話每天都在變,想必世界就會亂了,所以一般服務性的程式,往往需要一個固定的埠號,這就是所謂的埠綁定

綁定示例

#coding=utf-8
from socket import *

#1、創建socket套接字
udpSocket = socket(AF_INET,SOCK_DGRAM)

#2、綁定相關信息,如果一個網路程式不綁定,則系統會隨機分配
bindAddress = ("",7781)#ip地址和埠號,ip一般不用寫,表示本機的任何一個ip
udpSocket.bind(bindAddress)

#3、等待接收方發送消息
receiveData = udpSocket.recvfrom(1024)

#4、顯示對方發送的數據
print(receiveData)

#5、關閉socket套接字
udpSocket.close()

windows電腦發送信息

mac電腦接收信息如下:

說明:

  • 一個udp網路程式,可以不綁定,此時操作系統會隨機進行分配一個埠,如果重新運行次程式埠可能會發生變化
  • 一個udp網路程式,也可以綁定信息(ip地址,埠號),如果綁定成功,那麼操作系統用這個埠號來進行區別收到的網路數據是否是此進程的

 

七、udp網路通信過程

 

八、udp應用:多線程對話聊天實現

#coding=utf-8
from threading import Thread
from socket import *

#接收數據
def receiveInfo():
    while True:
        receiveData = udpSocket.recvfrom(1024)
        print("<<%s:%s"%(str(receiveData[1]),str(receiveData[0])))

#發送數據
def sendInfo():
    while True:
        sendData = input("")
        udpSocket.sendto(sendData.encode("gb2312"),(destIp,destPort))

udpSocket = None
destIp = ""
destPort = 0

def main():
    global udpSocket
    global destIp
    global destPort

    destIp = input("對方的IP:")
    destPort = int(input("對方的Port:"))

    udpSocket = socket(AF_INET,SOCK_DGRAM)
    udpSocket.bind(("",4567))#這裡寫兩個()的原因是將("",4567)當做一個整體元組使用

    tr = Thread(target = receiveInfo)
    ts = Thread(target = sendInfo)

    tr.start()
    ts.start()

    tr.join()
    ts.join()

if __name__ == '__main__':
    main()

Mac電腦上執行程式如下:

windows電腦上運行網路調試助手如下:

從而就是實現了基於socket的udp的聊天功能。

九、udp應用:多線程聊天室的實現

程式基本流程:創建接收端socket ---> 創建發送到socket ---> 啟動接收端socket ---> 啟動發送端socket ---> 等待用戶輸入 ---> 接收用戶輸入併發送到廣播 ---> 接收信息並顯示。

# -*- coding:utf-8 -*-
from socket import *
from time import ctime, sleep
import threading

class ChatRoomPlus:
    def __init__(self):
        # 全局參數配置
        self.encoding = "utf-8"  # 使用的編碼方式
        self.broadcastPort = 7788   # 廣播埠

        # 創建廣播接收器
        self.recvSocket = socket(AF_INET, SOCK_DGRAM)
        self.recvSocket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
        self.recvSocket.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
        self.recvSocket.bind(('', self.broadcastPort))

        # 創建廣播發送器
        self.sendSocket = socket(AF_INET, SOCK_DGRAM)
        self.sendSocket.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)

        # 其他
        self.threads = []

    def send(self):
        """發送廣播"""

        print("UDP發送器啟動成功...")
        self.sendSocket.sendto("***加入了聊天室".encode(self.encoding), ('255.255.255.255', self.broadcastPort))
        while True:
            sendData = input("請輸入需要發送的消息:")

            self.sendSocket.sendto(sendData.encode(self.encoding), ('255.255.255.255', self.broadcastPort))
            # print("【%s】%s:%s" % (ctime(), "我", sendData))

            sleep(1)

    def recv(self):
        """接收廣播"""

        print("UDP接收器啟動成功...")
        while True:
            # 接收數據格式:(data, (ip, port))
            recvData = self.recvSocket.recvfrom(1024)

            print("【%s】[%s : %s] : %s" % (ctime(), recvData[1][0], recvData[1][1], recvData[0].decode(self.encoding)))

            sleep(1)

    def start(self):
        """啟動線程"""

        t1 = threading.Thread(target=self.recv)
        t2 = threading.Thread(target=self.send)
        self.threads.append(t1)
        self.threads.append(t2)

        for t in self.threads:
            t.setDaemon(True)
            t.start()

        while True:
            pass


if __name__ == "__main__":
    demo = ChatRoomPlus()
    demo.start()

運行效果:

Mac電腦上運行

linux電腦上運行程式

windows上運行程式


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在python3中爬蟲常用基本庫為urllib以及requests 本文主要描述urllib的相關內容 urllib包含四個模塊:requests——模擬發送請求 error——異常處理模塊 parse——關於URL處理方法的工具模塊 robotparser——通過識別網站robot.txt判斷網站 ...
  • 這裡 sqlproxy起到一個代理的作用,使用時無需關註 mysql和oracle的實現 ...
  • 什麼是優先順序隊列? 怎麼實現一個優先順序隊列? PriorityQueue是線程安全的嗎? PriorityQueue就有序的嗎? ...
  • 此程式在Windows10 CodeBlocks17.12環境下測試運行,其他編程環境未經測試! 作業需求↓↓↓↓↓↓ 運行效果圖如下 (codeblocks下載地址http://www.codeblocks.org/downloads/binaries) C++代碼 2019-04-20-20:3 ...
  • 2.1 變數是程式的基本組成單位 舉一個簡單的例子 2.2 變數的介紹 2.2.1 概念 變數相當於記憶體中一個數據存儲空間的表示,可以把變數看作是一個房間的門牌號,通過門牌號我們可以找到對應的房間,而通過變數名可以訪問到變數(值)。 2.2.2 變數使用的基本步驟 1) 聲明/定義變數(Scala要 ...
  • String:是對象不是原始類型. 為不可變對象,一旦被創建,就不能修改它的值. 對於已經存在的String對象的修改都是重新創建一個新的對象,然後把新的值保存進去. String 是final類, 不能被繼承. StringBuffer: 是一個可變對象,當對他進行修改的時候不會像String那樣 ...
  • 一、numpy和matplotlib庫的學習筆記 (1)numpy庫 1,從數值範圍創建數組 1 numpy.arange(start, stop, step, dtype)#參數分別為起始值,終止值,步長和數據類型 2.創建等間隔一位數組 1 np.linspace(start, stop, nu ...
  • 1.成員變數和局部變數 1.1成員變數和局部變數定義 成員變數指的是類裡面定義的變數(field),局部變數指的是在方法里定義的變數。 成員變數無須顯示初始化,系統會自動在準備階段或創建該類的實例時進行預設初始化。 與成員變數不同,局部變數除了形參之外,都必須顯示初始化。 命名規則: 一個類里不能定 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...