使用python實(shí)現(xiàn)UDP通信方式
python UDP通信
1.打開虛擬通信程序,選擇UDP通信并選定收發(fā)數(shù)據(jù)的ip地址和port端口:

2.在虛擬機(jī)中編寫python程序與主機(jī)中的虛擬通信程序?qū)崿F(xiàn)數(shù)據(jù)傳輸:
# 注釋的標(biāo)注格式為:每行開頭則直接輸入#并空一格開始注釋
# 若在每行代碼后面加注釋,則空兩格輸入#再空一格開始注釋
import socket
# 使用udp收發(fā)數(shù)據(jù)
def main():
# 1.創(chuàng)建socket套接字
udp_socket = socket.socket(socket.AF_INET, sock.SOCK_DGRAM) # AF_INET表示使用ipv4,默認(rèn)不變,SOCK_DGRAM表示使用UDP通信協(xié)議
# 2.綁定端口port
local_addr = ("", 7878) # 默認(rèn)本機(jī)任何ip ,指定端口號7878
udp_socket.bind(local_addr) # 綁定端口
# 3.收發(fā)數(shù)據(jù)
send_data = input("請輸入您想要發(fā)送的數(shù)據(jù):" )
udp_socket.sendto(send_data.encode("utf-8"), ("10.80.34.68", 8080)) # 編碼成全球統(tǒng)一數(shù)據(jù)格式,用元組表示接收方ip和port
recv_data = udp_socket.recvfrom(1024) # 定義單次最大接收字節(jié)數(shù)
# 4.打印數(shù)據(jù)
recv_msg = recv_data[0] # 接收的元組形式的數(shù)據(jù)有兩個元素,第一個為發(fā)送信息
send_addr = recv_data[1] # 元組第二個元素為發(fā)信息方的ip以及port
print ("收到的信息為:", recv_msg.decode("gbk")) # 默認(rèn)從windows發(fā)出的數(shù)據(jù)解碼要用”gbk”,保證中文不亂碼
print ("發(fā)送方地址為:", str(send_addr)) # 強(qiáng)轉(zhuǎn)為字符串輸出地址,保證不亂碼
# 5.關(guān)閉套接字
udp_socket.close()
if __name__ == "__main__":
main()
對UDP協(xié)議的理解
Socket簡介
網(wǎng)絡(luò)中進(jìn)程之間如何通信
1,在本地可以通過進(jìn)程PID來唯一標(biāo)識一個進(jìn)程,但是在網(wǎng)絡(luò)中這是行不通的。
2,TCP/IP協(xié)議族已經(jīng)幫我們解決了這個問題,即:網(wǎng)絡(luò)層的ip地址可以唯一標(biāo)識網(wǎng)絡(luò)中的主機(jī);而傳輸層的:協(xié)議+端口,可以唯一標(biāo)識主機(jī)中的應(yīng)用程序(進(jìn)程)。
3,利用ip地址,協(xié)議,端口,就可以標(biāo)識網(wǎng)絡(luò)的進(jìn)程了,網(wǎng)絡(luò)中的進(jìn)程通信就可以利用這個標(biāo)識與其他進(jìn)程進(jìn)行交互。
什么是Socket?
socket,簡稱:套接字,是進(jìn)程間通信的一種方式。socket與其他進(jìn)程間的通信方式不同在于:它能實(shí)現(xiàn)不同主機(jī)間的進(jìn)程間通信。例如:QQ聊天、瀏覽網(wǎng)頁、收發(fā)Email等等。
創(chuàng)建Socket
在Python中socket模塊的函數(shù)socket:
socket.socket(AddressFamily,Type)
加以說明:
函數(shù)socket.socket創(chuàng)建一個socket,返回一個socket。
AddressFamily:選擇AF_INET用于網(wǎng)絡(luò)中進(jìn)程間通信或者AF_UNIX用于同一臺機(jī)器進(jìn)程間通信,實(shí)際工作中常用AF_INET。
Type:套接字類型,可以是SOCK_STREAM,流式套接字,主要用于tcp協(xié)議或者SOCK_DGRAM,數(shù)據(jù)報套接字,主要用于udp協(xié)議。
#import socket # udp:sock_dgram:數(shù)據(jù)報套接字 # udpSocket = socket(socket.AF_INET, socket.SOCK_DGRAM) # # # tcp:sock_stream:流式套接字 # tcpSocket = socket(AF_INET, SOCK_STREAM)
UDP特點(diǎn)
UDP:用戶數(shù)據(jù)報協(xié)議,是一個無連接的簡單的面向數(shù)據(jù)報的運(yùn)輸層協(xié)議。UDP不提供可靠性,它只是把應(yīng)用程序傳給IP層的數(shù)據(jù)報發(fā)送出去,但是并不能保證它們能到達(dá)目的地。由于UDP在傳輸數(shù)據(jù)報前不用在客戶和服務(wù)器之間建立一個連接,且沒有超時重發(fā)等機(jī)制,故而傳輸速度很快。
UDP:是一種面向無連接的協(xié)議,每個數(shù)據(jù)報都是一個獨(dú)立的信息,包括完整的源地址或目的地址,它在網(wǎng)絡(luò)上以任何可能的路徑傳往目的地,因此能否到達(dá)目的地,到達(dá)目的地的時間以及內(nèi)容的正確性都是不能被保證的
UDP是面向無連接的通訊協(xié)議,UDP數(shù)據(jù)包括目的端口號和源端口號信息,由于通訊不需要連接,所以可以實(shí)現(xiàn)廣播發(fā)送。
UDP傳輸數(shù)據(jù)時有大小限制,每個被傳輸?shù)臄?shù)據(jù)報必須限定在64KB之內(nèi)。
UDP是一個不可靠的協(xié)議,發(fā)送方所發(fā)送的數(shù)據(jù)報并不一定以相同的次序到達(dá)接收方。
UDP一般用于多點(diǎn)通信和實(shí)時的數(shù)據(jù)業(yè)務(wù)。例如:語音廣播、QQ、視頻會議系統(tǒng)等。
UDP中客戶端和服務(wù)器端交互
UDP中客戶端和服務(wù)器端交互

服務(wù)器端具體實(shí)現(xiàn)代碼如下:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author : xiaoke
import socket
# 服務(wù)端
def main():
# 1,創(chuàng)建數(shù)據(jù)報套接字
udpSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 2,綁定本地地址,核心是為綁定并公布端口
# ''表示指定任意ip:0.0.0.0,系統(tǒng)中任意ip的數(shù)據(jù)都可以接收
myAddr = ('', 8080)
udpSocket.bind(myAddr)
# 3,接收客戶端數(shù)據(jù),獲得客戶端的地址(ip和端口號)
recData, clientAddr = udpSocket.recvfrom(1024)
print(clientAddr)
print(recData.decode())
# 4,回復(fù)客戶端消息
udpSocket.sendto(recData, clientAddr)
# 5,關(guān)閉socket
udpSocket.close()
if __name__ == '__main__':
main()
echo服務(wù)器端具體實(shí)現(xiàn)代碼如下:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author : xiaoke
import socket
# echo服務(wù)端,回射服務(wù)器,發(fā)過來,彈回去
# 單進(jìn)程單線程,無連接
def main():
# 1,創(chuàng)建數(shù)據(jù)報套接字
udpSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 2,服務(wù)端需要綁定:目的是把端口號和ip地址暴露給別人,讓別人調(diào)用
# 表示指定任意ip:0.0.0.0,系統(tǒng)中任意ip的數(shù)據(jù)都可以接收
myAddr = ('', 8080)
udpSocket.bind(myAddr)
while True:
# 3,接收客戶端數(shù)據(jù),獲得客戶端的地址(ip和端口號)
recData, clientAddr = udpSocket.recvfrom(1024)
# print(clientAddr)
print(recData.decode())
# 4,回復(fù)客戶端消息
# udpSocket.sendto(recData, clientAddr)
sendData = input("服務(wù)器!請輸入提供的數(shù)據(jù):")
udpSocket.sendto(sendData.encode(), clientAddr)
# 5,關(guān)閉socket
udpSocket.close()
if __name__ == '__main__':
main()
客戶端具體實(shí)現(xiàn)代碼如下:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author : xiaoke
import socket
# 客戶端
def main():
# 1,創(chuàng)建udp類型的socket
udpSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 2,指定目的地址(ip和端口號
serverAddr = ('192.168.105.125', 8080)
while True:
# 3,發(fā)送數(shù)據(jù)
sendData = input("客戶端!請輸入請求數(shù)據(jù):")
udpSocket.sendto(sendData.encode(), serverAddr)
# 4,接收數(shù)據(jù)是一個元組,本次接收數(shù)據(jù)的最大長度,建議是2^xxx次方
receData, peerAddr = udpSocket.recvfrom(1024)
print(receData.decode())
# print(peerAddr)
# 5,關(guān)閉socket
udpSocket.close()
if __name__ == '__main__':
main()
綁定端口的說明:
1,一般情況下,在電腦上運(yùn)行的網(wǎng)絡(luò)程序有很多,而各自用的端口號很多情況下不知道,為了不與其他的網(wǎng)絡(luò)程序占用同一個端口號,往往在編程中,udp的端口號一般不綁定。但是如果需要做成一個服務(wù)器端的程序的話,是需要綁定的。
2,一個udp網(wǎng)絡(luò)程序,可以不綁定端口,此時操作系統(tǒng)會隨機(jī)進(jìn)行分配一個端口,如果重新運(yùn)行此程序,端口可能會發(fā)生變化。
3,一個udp網(wǎng)絡(luò)程序,也可以綁定信息(ip地址,端口號),如果綁定成功,那么操作系統(tǒng)用這個端口號來進(jìn)行區(qū)分收到的網(wǎng)絡(luò)數(shù)據(jù)是否是此進(jìn)程的。
UDP網(wǎng)絡(luò)通信過程

多線程聊天室服務(wù)器端的實(shí)現(xiàn)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author : xiaoke
import socket
from threading import Thread
def task_recv(s):
while True:
recvData, peerAddr = s.recvfrom(1024)
print('子線程接收:ip地址 %s : 消息 %s' % (str(peerAddr), recvData.decode()))
def task_send(s, addr):
while True:
sendData = input('親!請?zhí)峁┓祷氐臄?shù)據(jù):')
s.sendto(sendData.encode(), addr)
def main():
# 1.創(chuàng)建udp數(shù)據(jù)報套接字
serverSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 2.綁定本地地址,核心是為綁定并公布端口
myAddr = ('', 8080) # ''表示指定任意ip 0.0.0.0 系統(tǒng)中任意ip的數(shù)據(jù)都可以接收
serverSocket.bind(myAddr)
# 3.主線程收到消息,獲得對方的ip,port
recvData, peerAddr = serverSocket.recvfrom(1024)
print('主線程接收:ip地址 %s : 消息 %s' % (str(peerAddr), recvData.decode()))
# 4.啟動接收消息線程
thread_recv = Thread(target=task_recv, args=(serverSocket,))
thread_recv.start()
# 5.再啟動發(fā)送消息的線程,傳遞對方的ip port
thread_send = Thread(target=task_send, args=(serverSocket, peerAddr))
thread_send.start()
# 6,等待子線程結(jié)束
thread_recv.join()
thread_send.join()
if __name__ == "__main__":
main()
UDP中廣播
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author : xiaoke
from socket import *
def main():
# 1,創(chuàng)建socket,數(shù)據(jù)報套接字
udp_socket = socket(AF_INET, SOCK_DGRAM)
# 2,設(shè)置允許廣播
# 設(shè)置socket屬性,是否允許廣播,1就是允許
udp_socket.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
# 3,指定廣播地址(“broadcast”,2425)
broadcast_addr = ('<broadcast>', 8080)
# 4,發(fā)送消息,以下以飛秋軟件演示
send_data = b'1:100:will:will-pc:32:will broadcast'
udp_socket.sendto(send_data, broadcast_addr)
udp_socket.close()
if __name__ == '__main__':
main()
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
利用Pandas 創(chuàng)建空的DataFrame方法
下面小編就為大家分享一篇利用Pandas 創(chuàng)建空的DataFrame方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-04-04
Python?RawString與open文件的newline換行符遇坑解決
這篇文章主要為大家介紹了Python?RawString與open文件的newline換行符遇坑解決示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10
Django項(xiàng)目主urls導(dǎo)入應(yīng)用中views的紅線問題解決
這篇文章主要介紹了Django項(xiàng)目主urls導(dǎo)入應(yīng)用中views的紅線問題解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-08-08
Python通過OpenCV的findContours獲取輪廓并切割實(shí)例
這篇文章主要介紹了Python通過OpenCV的findContours獲取輪廓并切割實(shí)例,具有一定借鑒價值,需要的朋友可以參考下2018-01-01
Python 實(shí)現(xiàn) WebSocket 通信的過程詳解
WebSocket是一種在Web應(yīng)用程序中實(shí)現(xiàn)雙向通信的協(xié)議,與傳統(tǒng)的HTTP請求-響應(yīng)模型不同,WebSocket允許服務(wù)器主動向客戶端推送數(shù)據(jù),實(shí)現(xiàn)實(shí)時性和互動性,這篇文章主要介紹了Python 實(shí)現(xiàn) WebSocket 通信的過程詳解,需要的朋友可以參考下2024-06-06
Django查詢數(shù)據(jù)庫的性能優(yōu)化示例代碼
這篇文章主要給大家介紹了關(guān)于Django查詢數(shù)據(jù)庫性能優(yōu)化的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-09-09

