Python高级 Day3 网络udp
一、网络通信概述(了解)
所谓的网络编程就是,让在网络中不同的电脑上的软件能够进行数据传递,即网络中不同主机进程之间的通信
二、IP地址
1. IP地址的作用
概念:ip地址 : 互联网协议地址(internet protocol address)
作用: 用来在网络中标记一台电脑,比如192.168.110.111;在同一网络中是唯一的。
2. IP地址组成
1. 目前ip地址两种表示方式:
C:\Users\pc-lijun>ipconfig
本地链接 IPv6 地址. . . . . . . . : fe80::5cd5:4752:60c6:616a%6
IPv4 地址 . . . . . . . . . . . . : 192.168.110.111
子网掩码 . . . . . . . . . . . . : 255.255.255.0
默认网关. . . . . . . . . . . . . : 192.168.110.1
1. ipv4: ipv4是目前的主流, 由32位二进制构成,分为4段,每段范围0-255,比如192.168.110.111
2. ipv6: ipv6是未来 ,由128位二进制构成, 2的128次方 /2的32次方 比如:fe80::5cd5:4752:60c6:616a%6
2. IP地址包括两部分:
针对ipv4:
ip地址组成=网络号+主机号 ,好比电话号码由区号+电话主机号组成 020-12345678
3. IP地址的分类(了解)
ip地址分类:
A类: 大型网络,比如互联网
B类: 中型网络
C类: 小型网络,比如局域网
4. 两种特殊的ip地址
1. 私有ip: 在这么多网络IP中,国际规定有一部分IP地址是用于我们的局域网使用,也就
是属于私网IP,不在公网中使用的
2. 用于做回路测试的ip
IP地址127.0.0.1~127.255.255.255用于回路测试,比如127.0.0.1代表本机
三、Linux命令(ifconfig,ping)
1. 查看或者配置网卡信息:ifconfig
a>查看ip地址
- windows环境: ipconfig
- ubuntu环境: ifconfig
网卡名称: ens33
硬件地址 00:0c:29:63:95:db(网卡的物理编码,mac地址)
ipv4: inet 地址:192.168.110.112
广播地址: :192.168.110.255
掩码:255.255.255.0
ipv6地址: inet6 地址: fe80::bc92:8424:c45e:464/64 Scope:Link
b>开启和关闭网卡
格式: sudo ifconfig <网卡名称> down|up
关闭: sudo ifconfig ens33 down
开启: sudo ifconfig ens33 up
c>修改网卡ip地址
格式: sudo ifconfig <网卡名称> <新ip地址>
sudo ifconfig ens33 192.168.110.116
不建议自己手动设置ip
ipconfig, ifconfig
ip if(interface:网络接口)
2. 测试远程主机连通性:ping
1. ping ip
1. ubuntu--> windows
ping 192.168.110.111
2. windows-->ubuntu
C:\Users\pc-lijun>ping 192.168.110.112
正在 Ping 192.168.110.112 具有 32 字节的数据:
来自 192.168.110.112 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.110.112 的回复: 字节=32 时间<1ms TTL=64
2. ping 域名
示例1: ping 百度,博学谷,本机的域名
www.baidu.com(百度域名)、tlias3.boxuegu.com(博学谷域名)、localhost(本机域名)
localhost: 本机的域名, 127.0.0.1: 代表本机
四、端口
1. 端口概述
简单的说: 操作系统通过端口来区分不同的网络程序(进程),是网络程序对外传输数据的出入口
2. 端口号
用来标识端口的,由两个字节构成, 范围0-65535
3. 端口如何分配 : 操作系统(主机)来分配
a> 知名端口
名端口是众所周知的端口号,范围从0到1023
- http: 80端口
- ssh : 22端口
- ftp: 21端口
- telnet: 23端口
b> 动态分配端口
动态端口的范围是从1024到65535之所以称为动态端口,是因为它一般不固定分配某种服务,而是动态分配。
动态分配是指当一个程序需要网络通信时,它向主机(操作系统)申请一个端口,主机(操作系统)从可用的端口号中分配一个供它使用。
当这个程序关闭时,同时也就释放了所占用的端口号
4. 怎样查看端口
a> netstat : net status(网络状态)
-n: 以数字的形式显示端口
- a: 显示所有的状态
命令: netstat -na
b> lsof :list open file 列出打开的文件,列出运行的程序
-i select IPv[46] files ,选择与ip相关的文件
示例1:查看涉及ip访问的程序
sudo lsof -i
示例2:查看端口22被哪个程序占用
sudo lsof -i:22
杀死某个进程:
sudo kill pid
pid: 进程的id
五、socket简介
1. 不同电脑上的进程如何标识
ip地址+端口号+通信方式(udp/tcp...)
2. 什么是Socket: 套接字
socket(简称 套接字) 是进程间通信的一种方式,它与其他进程间通信的一个主要不同是:
它能实现不同主机间的进程间通信, 几乎所有的不同主机之间的通信(网络通信)都采用socket通信
3. 创建socket的基本流程
1. 写数据到文件的流程
- 创建或者打开文件,取得文件对象file
- 通过file对象读写数据
- 关闭文件对象
2. 使用socket通信的基本流程
1. 创建socket对象(udp,tcp)
2. 通过socket对象收发数据
3. 关闭socket对象
函数 socket.socket 创建一个 socket,该函数带有两个参数:
Address Family:地址族,可以选择 AF_INET(用于 Internet 进程间通信) 或者 AF_UNIX(用于同一台机器进程间通信),实际工作中常用AF_INET
Type:套接字类型,可以是 SOCK_DGRAM(数据报套接字,主要用于 UDP 协议)或者 SOCK_STREAM(流式套接字,主要用于 TCP 协议)
六、udp 网络程序-发送与接收数据(重点)
1. udp网络程序-发送数据编程实现
实现步骤:
1. 导入socket模块
2. 创建udp-socket对象
3. 通过socket对象发送数据
4. 关闭socket对象
2. udp网络程序-接收数据编程实现
"""udp网络程序-发送数据编程实现
实现步骤:
1. 创建udp-socket对象
2. 通过socket对象发送数据
3. 通过socket接收数据
3. 关闭socket对象
"""
import socket
def main():
# 1. 创建udp-socket对象
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
"""2.通过socket对象发送数据
sendto(data, address)
1. data: 要发送给目标主机的数据
2. address:目标主机的地址: the address is a pair (hostaddr, port)
"""
# 2.1 取得要发送的数据
send_data = input("请输入您要发的数据:")
dest_address = ('192.168.110.111', 8080) # 是元组类型,且第一个元素是ip地址,是字符串类型 ,第二个元素是端口,整数类型
# 把字符串转为二进制串,即编码
data = send_data.encode('utf-8')
udp_socket.sendto(data, dest_address)
#3. 等待接收从目标主机中接收回传的消息,阻塞状态
recv_data=udp_socket.recvfrom(1024) # buffersize: 缓存的大小, 一次最多接收1024字节
"""显示接收到的数据
(b'good', ('192.168.110.111', 8080))
- 接收的数据封装在元组中
- 第一个元素: 具体的内容,是二进制串
- 第二个元素: 目标主机的地址信息
"""
# print(recv_data)
# 把二进制串转为字符串 解码
data=recv_data[0].decode('utf-8')
print(data)
# 4. 关闭socket对象
udp_socket.close()
if name == 'main':
main() # alt+enter : 快速修复
七、python编码转换
1. 为何要编码传输
因为网络传输是采用二进制信号进行传输的, 所以字符串、图片等格式的数据都需要编码成为二进制字节串才能传输
2. 常见的编码方式有哪些
gbk: 支持中文,面向大中华区,windows的默认编码方式
utf-8 : 支持中文,面向全球,linux的默认方式,一般使用utf-8
3. 乱码产生的原因
1.编码解码不支持中文
2. 编码与解码不一致
4. 如何实现编码转换
string->bytes:encode编码
例如:bytes= "你好".encode("utf-8")
bytes->string:decode解码
例如:string=bytes.decode("utf-8")
八、UDP端口绑定问题
"""udp网络程序-发送数据编程实现
实现步骤:
1. 创建udp-socket对象
2. 通过socket对象发送数据
3. 关闭socket对象
"""
import socket
def main():
# 1. 创建udp-socket对象
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 绑定端口, 先绑定再使用
# address:the address is a pair (host, port) : 元组类型,第一个是本机的ip,第二个是端口号
local_addr=('',9999) # 本机的ip一般不指定, 设置为'' ,中间不能有空格
udp_socket.bind(local_addr)
"""2.通过socket对象发送数据
sendto(data, address)
1. data: 要发送给目标主机的数据
2. address:目标主机的地址: the address is a pair (hostaddr, port)
"""
# 2.1 取得要发送的数据
send_data = input("请输入您要发的数据:")
dest_address = ('192.168.110.111', 8080) # 是元组类型,且第一个元素是ip地址,是字符串类型 ,第二个元素是端口,整数类型
# 把字符串转为二进制串,即编码
data = send_data.encode('utf-8')
udp_socket.sendto(data, dest_address)
# 3. 关闭socket对象
udp_socket.close()
if name == 'main':
main() # alt+enter : 快速修复
九、案例:udp聊天器
1. 需求分析
编写程序,有2个功能
1.获取键盘数据,并将其发送给对方
2.接收数据并显示
并且可以选择以上的2个功能调用
2. 界面效果
简易版upd聊天器
==============================
1. 发送消息
2. 接收消息
3. 退出聊天
==============================
请输入您选择的功能:
import socket
def send_msg(udp_socket):
"""发送消息"""
send_data = input("请输入要发送的消息:")
dest_addr = ('192.168.110.111', 8080)
# 编码
data=send_data.encode('utf-8')
udp_socket.sendto(data,dest_addr)
def recv_msg(udp_socket):
"""接收消息"""
# 等待接收目标主机回传的消息
recv_data=udp_socket.recvfrom(1024)
# 解码
data=recv_data[0].decode('gbk')
# 显示接收的数据
print(data)
def main():
# 1. 创建udp socket对象
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 2.绑定端口
udp_socket.bind(('', 9999))
# 3. 显示菜单界面
while True:
print("简易版udp聊天器")
print("=" * 30)
print("1. 发送消息")
print("2. 接收消息")
print("0. 退出聊天")
print("=" * 30)
# 接收用户的功能选择
opt = input("请输入你的选择:")
if opt == '1':
send_msg(udp_socket)
elif opt == '2':
recv_msg(udp_socket)
elif opt == '0':
break
else:
print("您的输入有误,请重新输入")
# 4.关闭socket
udp_socket.close()
if name == 'main':
main()
十、其他
pycharm快捷键
1. Ctrl + Alt + L 代码格式化(在pycharm中需额外配置)
在file-->setting 搜索: reformat
2. Alt + Enter 快速修正错误
输入:main 选择 if __name__ == '__main__':
再输入 ma 选择main()
鼠标点中main,按alt + enter 选择定义函数
3. ctrl+alt+v 自动生成局部变量
4. ctrl+mouse wheel 通过鼠标滚轮自动缩放代码字体的大小
在file-->setting 搜索: wheel
5. ctrl+alt+m 抽取方法
6. ctrl+d 复制一行
7. ctrl+x 删除一行
8. Ctrl + P 查看参数信息
9. Ctrl + Q 快速查看文档
10. ctrl+F 在文档中查找内容
11. shift+f6 重命名文件
12. ctrl+点击鼠标 进入鼠标指向的类或者方法,查看源码
13. Ctrl + Alt + O 优化导入
14. Ctrl + Alt + I 自动缩进