python --- udp的使用
1. python的模塊導(dǎo)入規(guī)則
參考
1.1 系統(tǒng)自帶模塊
系統(tǒng)自帶的模塊直接import導(dǎo)入
import time import unittest1.2 第三方下載模塊
第三方下載模塊也可以直接導(dǎo)入
import HTMLTestRunner import requests1.3 導(dǎo)入模塊的部分函數(shù)或類(lèi)
from time import sleep,strftime from time import *1.4 導(dǎo)入自己寫(xiě)的模塊
- 同文件夾: 直接import模塊名
- 跨文件夾: from [文件夾.文件夾.模塊] import [類(lèi)(或函數(shù))]
例如自定義了2個(gè)加法如下:
# class01/myAdd2.pydef myAdd2(a, b):print("自定義加法2")return a + b # class02/myAdd2.pydef myAdd1(a, b):print("自定義加法1")return a + b在文件夾class01下面創(chuàng)建一個(gè)addTest文件測(cè)試導(dǎo)入自己的加法模塊
from class01.myAdd2 import myAdd2 from class02.myAdd1 import myAdd1print(myAdd2(1,3)) print("*************") print(myAdd1(2,4))2. 網(wǎng)絡(luò) - udp
參考
2.1 網(wǎng)絡(luò)通信概述
- 網(wǎng)絡(luò)就是一種輔助雙方或者多方能夠連接在一起的工具
- 使用網(wǎng)絡(luò)的目的:
- 聯(lián)通多方進(jìn)行通信,把數(shù)據(jù)從一方傳遞給另外一方
- 為了讓不同電腦上運(yùn)行的軟件之間能夠互相傳遞數(shù)據(jù),就需要借助網(wǎng)絡(luò)的功能
- 總的來(lái)說(shuō):
- 使用網(wǎng)絡(luò)能夠把多方鏈接在一起,然后可以進(jìn)行數(shù)據(jù)傳遞
- 所謂網(wǎng)絡(luò)編程就是,讓在不同的電腦上的軟件能夠進(jìn)行數(shù)據(jù)傳遞,即進(jìn)程之間的通信
2.2 ip地址(重點(diǎn))
- 地址就是用來(lái)標(biāo)記地點(diǎn)的
- ip地址: 用來(lái)在網(wǎng)絡(luò)種標(biāo)記一臺(tái)電腦,比如: 192.168.1.1; 在本地局域網(wǎng)上是唯一的
- 每一個(gè)ip地址包括兩部分: 網(wǎng)絡(luò)地址和主機(jī)地址
2.2.1 A類(lèi)ip地址
一個(gè)A類(lèi)IP地址由1字節(jié)的網(wǎng)絡(luò)地址和3字節(jié)的主機(jī)地址組成,網(wǎng)絡(luò)地址的最高位必須是"0",
地址范圍: 1.0.0.1 ~ 126.255.255.254
二進(jìn)制表示為: 00000001 00000000 00000000 00000001 ~ 011111110 11111111 11111111 11111110
可用的A類(lèi)網(wǎng)絡(luò)有126個(gè),每個(gè)網(wǎng)絡(luò)能容納 1677214個(gè)主機(jī)
2.2.2 B類(lèi)ip地址
一個(gè)B類(lèi)IP地址由兩個(gè)字節(jié)的網(wǎng)絡(luò)地址和2個(gè)字節(jié)的主機(jī)地址組成,網(wǎng)絡(luò)地址的最高位必須是"10"
地址范圍: 128.1.0.1 ~ 191.255.255.254
二進(jìn)制表示位: 10000000 00000001 00000000 00000001 ~ 10111111 11111111 11111111 11111110
可用的B類(lèi)網(wǎng)絡(luò)由16384各,每個(gè)網(wǎng)絡(luò)能容納65534主機(jī)
2.2.3 C類(lèi)ip地址
一個(gè)C類(lèi)IP地址由3字節(jié)的網(wǎng)絡(luò)地址和1字節(jié)的主機(jī)地址組成,網(wǎng)絡(luò)地址的最高位必須是"110"
地址范圍: 192.0.1.1 ~ 223.255.255.254
二進(jìn)制表示位: 11000000 00000000 00000001 00000001 ~ 11011111 11111111 11111110 11111110
C類(lèi)網(wǎng)絡(luò)可達(dá)2097152各,每個(gè)網(wǎng)絡(luò)能容納254個(gè)主機(jī)
2.2.4 D類(lèi)地址用于多點(diǎn)廣播
d類(lèi)ip地址第一個(gè)字節(jié)以"1110"開(kāi)始,它是一個(gè)專(zhuān)門(mén)保留的地址
它并不指向特定的網(wǎng)絡(luò),目前這一地址被用在多點(diǎn)廣播中
多點(diǎn)廣播地址用來(lái)依次尋址一組計(jì)算機(jī), 地址范圍: 224.0.0.1 ~ 239.255.255.254
2.2.5 E類(lèi)ip地址
以"1111"開(kāi)頭,位將來(lái)使用保留
E類(lèi)地址保留,僅作實(shí)驗(yàn)和開(kāi)發(fā)用
2.2.6 私有ip
這么多網(wǎng)絡(luò)ip中,國(guó)際規(guī)定有一部分ip地址是給我們的局域網(wǎng)使用,也就是屬于私網(wǎng)ip,不在公網(wǎng)中使用,它們的范圍是:
10.0.0.0 ~ 10.255.255.255172.16.0.0 ~ 172.31.255.255192.168.0.0 ~ 192.168.255.2552.2.7 注意
ip地址 127.0.0.1 ~ 127.255.255.255 用于回路測(cè)試
如: 127.0.0.1 可以代表本機(jī)ip地址, 用 http://127.0.0.1就可以測(cè)試本機(jī)種配置的web服務(wù)器
2.3 Linux命令(ping、ipconfig等)
- 本地網(wǎng)卡 :又叫本地回環(huán),用來(lái)測(cè)試電腦是否能夠進(jìn)行正常的網(wǎng)絡(luò)通信.
- 在linux中查看網(wǎng)卡信息: ifconfig
- 假設(shè)網(wǎng)卡的名字位 ens40,關(guān)閉該網(wǎng)卡: sudo ifconfig ens40 down
- 打開(kāi)該網(wǎng)卡: sudo ifconfig ens40 up
2.4 端口(重點(diǎn))
- ip是區(qū)分主機(jī)用的,端口是區(qū)分同一個(gè)主機(jī)種不同進(jìn)程用的
- 端口就好比一個(gè)房子的門(mén),是出入這件房子的必經(jīng)之路
- 如果一個(gè)程序需要收發(fā)網(wǎng)絡(luò)數(shù)據(jù),那么就需要這樣的端口
- 操作系統(tǒng)為了統(tǒng)一管理,對(duì)其進(jìn)行了編號(hào),這就是端口號(hào)
2.4.1 端口號(hào)
端口是通過(guò)端口號(hào)來(lái)標(biāo)記的,端口號(hào)只有整數(shù),范圍是從0到65535
端口數(shù)不一樣的*nix系統(tǒng)不一樣,還可以手動(dòng)修改
進(jìn)程與程序: 一個(gè)程序在沒(méi)有運(yùn)行起來(lái)的時(shí)候叫進(jìn)程,在運(yùn)行起來(lái)之后叫程序
2.4.2端口是怎樣分配的
端口號(hào)不是隨意使用的,而是按照一定的規(guī)定進(jìn)行分配
端口的分類(lèi)標(biāo)準(zhǔn)有好幾種,下面只介紹一下知名端口和動(dòng)態(tài)端口
知名端口: 是眾所周知的端口號(hào),范圍從 0 到 1023
80端口分配給HTTP服務(wù)
21端口分配給FTP服務(wù)
可以理解為,一些常用的功能使用的端口
動(dòng)態(tài)端口: 范圍從 1024 到 65535
之所以是動(dòng)態(tài)端口, 是因?yàn)樗话悴还潭ǚ峙淠撤N服務(wù),而是動(dòng)態(tài)分配
動(dòng)態(tài)分配: 當(dāng)一個(gè)系統(tǒng)程序或應(yīng)用程序需要網(wǎng)絡(luò)通信時(shí),它向主機(jī)申請(qǐng)一個(gè)端口,主機(jī)從可用的端口號(hào)種分配一個(gè)供它使用,當(dāng)這個(gè)程序關(guān)閉時(shí),同時(shí)也就釋放了所占用的端口號(hào)
2.4.3 小結(jié)
一臺(tái)有ip的主機(jī)可以提供許多服務(wù),比如HTTP、FTP、SMTP等,這些服務(wù)完全可以通過(guò)一個(gè)ip地址來(lái)實(shí)現(xiàn)。那么主機(jī)是怎么樣區(qū)分不同的網(wǎng)絡(luò)服務(wù)呢? 顯然不能只靠ip地址,因?yàn)閕p地址與網(wǎng)絡(luò)服務(wù)的關(guān)系是一對(duì)多的關(guān)系。實(shí)際上是通過(guò)"ip + 端口號(hào)"來(lái)區(qū)分不同的服務(wù)的。
2.5 socket簡(jiǎn)介
2.5.1 不同電腦上的進(jìn)程之間如何通信
首要解決的問(wèn)題是如何唯一標(biāo)識(shí)一個(gè)進(jìn)程,否則通信無(wú)從談起!
在1臺(tái)電腦上可以通過(guò)進(jìn)程號(hào)(PID)來(lái)唯一標(biāo)識(shí)一個(gè)進(jìn)程,但是在網(wǎng)絡(luò)種這是行不通的.
其實(shí)TCP/IP協(xié)議族已經(jīng)幫我們解決了這個(gè)問(wèn)題,網(wǎng)絡(luò)層的"ip地址"可以唯一標(biāo)識(shí)網(wǎng)絡(luò)種的主機(jī),而傳輸層的"協(xié)議+端口"可以唯一標(biāo)識(shí)主機(jī)種的應(yīng)用進(jìn)程(進(jìn)程)
這樣利用"ip地址、協(xié)議、端口"就可以標(biāo)識(shí)網(wǎng)絡(luò)中的進(jìn)程了,網(wǎng)絡(luò)中的進(jìn)程通信就可以利用這個(gè)標(biāo)志與其它進(jìn)程進(jìn)行交互
注意:
- 所謂進(jìn)程指的是: 運(yùn)行的程序以及運(yùn)行時(shí)用到的資源這個(gè)整體稱(chēng)為進(jìn)程
- 所謂進(jìn)程通信指的是: 運(yùn)行的程序之間的數(shù)據(jù)共享
2.5.2 什么是socket
socket(簡(jiǎn)稱(chēng): 套接字)是進(jìn)程通信的一種方式,它與其他進(jìn)程通信的一個(gè)主要不同是: 它能實(shí)現(xiàn)不同主機(jī)的進(jìn)程間通信,我們網(wǎng)絡(luò)上各種各樣的服務(wù)大多是基于Socket來(lái)完成通信的.下面是在python中使用socket的代碼
2.5.3 創(chuàng)建socket
在python中使用socket模塊的函數(shù)socket就可以完成:
import socket socket.socket(AddressFamily, Type)說(shuō)明:
函數(shù) socket.socket創(chuàng)建一個(gè)socket,該函數(shù)帶有兩個(gè)參數(shù):
- Address Family: 可以選擇 AF_INET(用于internet進(jìn)程間通信) 或者 AF_UNIX(同一臺(tái)機(jī)器進(jìn)程間通信),實(shí)際工作中常用AF_INET
- Type: 套接字類(lèi)型,可以是 SOCK_STREAM(流式套接字, 主要用于 TCP協(xié)議)或者 SOCK_DGRAM(數(shù)據(jù)報(bào)套接字,主要用于UDP協(xié)議)
創(chuàng)建一個(gè)tcp socket(tcp套接字)
import socket# 創(chuàng)建tcp的套接字 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# ...這里是使用套接字的功能 (省略) ...# 不用的時(shí)候,關(guān)閉套接字 s.close()創(chuàng)建一個(gè)udp socket(udp套接字)
import socket# 創(chuàng)建udp的套接字 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)# ...這里是使用套接字的而功能 (省略) ...# 不用的時(shí)候,關(guān)閉套接字 s.close()說(shuō)明:
- 套接字使用流程與文件的使用流程很類(lèi)似
- 創(chuàng)建套接字
- 使用套接字 收/發(fā) 數(shù)據(jù)
- 關(guān)閉套接字
2.6 udp網(wǎng)絡(luò)程序 - 發(fā)送、接受數(shù)據(jù)
2.6.1 使用socket發(fā)送upd數(shù)據(jù)
# 網(wǎng)絡(luò)編程/01-socket的基本使用 import socketdef main():# 1.創(chuàng)建一個(gè)udp套接字udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)# 2. 準(zhǔn)備接收方的地址# "192.168.1.103" 表示目的ip地址# 8080表示目的端口dest_addr = ("192.168.0.106", 8080) # 地址是元組, ip是字符串,端口是數(shù)字# 3. 從鍵盤(pán)獲取數(shù)據(jù)send_data = input("請(qǐng)輸入要發(fā)送的數(shù)據(jù): ")# 4. 發(fā)送數(shù)據(jù)到指定的電腦上的指定程序中udp_socket.sendto(send_data.encode("utf-8"), dest_addr)# 5. 關(guān)閉套接字udp_socket.close()print("----------run----------")if __name__ == "__main__":main().encode: 將前面的數(shù)據(jù)編碼
【栗子】: 改寫(xiě)上面的栗子,變?yōu)榭梢匝h(huán)發(fā)送
# 網(wǎng)絡(luò)編程/03-socket的基本使用 import socketdef main():upd_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)while True:send_data = input("請(qǐng)輸入要發(fā)送的數(shù)據(jù)(exit退出): ")# 如果輸入的數(shù)據(jù)是 exit, 退出if send_data == "exit":breakelse:dest_addr = ("192.168.0.106", 8080)upd_socket.sendto(send_data.encode("utf-8"), dest_addr)upd_socket.close()if __name__ == "__main__":main()2.6.2 使用socket接受udp數(shù)據(jù)
如果你的程序想收到數(shù)據(jù),必須得有一個(gè)固定的端口,將會(huì)造成數(shù)據(jù)丟失.
下面提供了一個(gè)綁定端口的API
from socket import *def main():# 1. 創(chuàng)建套接字udp_socket = socket(AF_INET, SOCK_DGRAM)# 2. 綁定本地的相關(guān)信息,如果一個(gè)網(wǎng)絡(luò)程序不綁定,則系統(tǒng)隨機(jī)分配local_addr = ("192.168.0.106", 7788) # ip地址和端口號(hào),ip一般不用寫(xiě),表示本既的任何一個(gè)ipudp_socket.bind(local_addr)# 3. 等待接收方發(fā)送的數(shù)據(jù)recv_data = udp_socket.recvfrom(1024) # 表示本次接收的最大字節(jié)數(shù)# 4. 顯示接收到的數(shù)據(jù)print(recv_data[0].decode('utf-8'))# 5. 關(guān)閉套接字udp_socket.close()if __name__ == "__main__":main()2.7 upd綁定端口問(wèn)題(重點(diǎn))
2.7.1 在發(fā)送信息前綁定端口號(hào)
一般來(lái)說(shuō),在發(fā)送信息前,都會(huì)先綁定端口號(hào),這樣方便收到接收端的信息
from socket import *def main():udp_socket = socket(AF_INET, SOCK_DGRAM)# 給udp綁定一個(gè)端口號(hào)udp_socket.bind(("", 7890))while True:send_data = input("請(qǐng)輸入要傳輸?shù)臄?shù)據(jù): ")if send_data == "exit":breakelse:udp_socket.sendto(send_data.encode("utf-8"), ("192.168.0.106", 8080))udp_socket.close()if __name__ == "__main__":main()在同一時(shí)刻,一個(gè)端口號(hào)只能綁定一個(gè)進(jìn)程. 如果某一個(gè)端口被占用,其他的程序?qū)o(wú)法使用該端口號(hào)
2.7.2 小結(jié)
1. 創(chuàng)建套接字
udp_socket = socket(AF_INET, SOCK_DGRAM)2. 綁定端口號(hào)
udp_bind(("", 7890))3. 使用套接字收發(fā)數(shù)據(jù)
# 發(fā)送數(shù)據(jù) udp_socket.sendto("xxx".encode("gbk"), ("192.168.0.1",8080))# 接收數(shù)據(jù) udp_socket.recvfrom(1024) # 1024 代表一次接收的大小4. 關(guān)閉套接字
udp_socket.close()測(cè)試用的工具: mNetAssist
2.8 案例: udp聊天器
說(shuō)明:
- 在電腦上編寫(xiě)程序,需求如下:
本地回環(huán)的使用:
如果你想在本地測(cè)試一下,數(shù)據(jù)在不同進(jìn)程之間的通信,可以使用本地回環(huán)網(wǎng)卡, ip地址為 127.0.0.1. 它是固定不變的。注意本地回環(huán),不能用于網(wǎng)絡(luò)通信~
from socket import *def send_msg(udp_socket):# 1.獲取鍵盤(pán)數(shù)據(jù),并將其發(fā)送給對(duì)方msg = input("\n請(qǐng)輸入要發(fā)送的數(shù)據(jù): ")# 2. 輸入對(duì)方的ip地址dest_ip = input("\n請(qǐng)輸入對(duì)方的ip地址: ")# 3. 輸入對(duì)方的portdest_port = int(input("\n請(qǐng)輸入對(duì)方的port: "))# 4. 發(fā)送數(shù)據(jù)udp_socket.sendto(msg.encode("gbk"), (dest_ip, dest_port))def recv_msg(udp_socket):# 1. 接收數(shù)據(jù)recv_msg = udp_socket.recvfrom(1024)print(recv_msg[0].decode("gbk"))def main():udp_socket = socket(AF_INET, SOCK_DGRAM)send_msg(udp_socket)recv_msg(udp_socket)udp_socket.close()if __name__ == "__main__":main()-
以上程序在數(shù)據(jù)發(fā)送成功之后,會(huì)進(jìn)入一種阻塞狀態(tài)(在此狀態(tài)下該端口號(hào)下的進(jìn)程不會(huì)做任何事,等待喚醒)
-
套接字是一個(gè)可以同時(shí)收發(fā)數(shù)據(jù)的,下面說(shuō)說(shuō) 單工、半雙工、全雙工的概念:
- 單工: 考慮收音機(jī),只能收而不能發(fā)送信息
- 半雙工: 考慮對(duì)講機(jī), 同一時(shí)刻只能發(fā)送或者接收信息.不能同時(shí)進(jìn)行
- 全雙工: 考慮打電話(huà),可以同時(shí)進(jìn)行收發(fā)信息(注意,套接字是全雙工的~)
操作系統(tǒng)會(huì)先將某個(gè)端口的數(shù)據(jù)存在內(nèi)存中,當(dāng)有程序調(diào)用將進(jìn)程的數(shù)據(jù)時(shí),會(huì)從操作系統(tǒng)中拿到該端口下的數(shù)據(jù)
總結(jié)
以上是生活随笔為你收集整理的python --- udp的使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: zblog php 外部调用,ZBlog
- 下一篇: python --- 使用socket