1、网络传输方式-UDP
这是我参与更文挑战的第11天,活动详情查看: 更文挑战
1.1UDP概念
# UDP:英文全拼(User Datagram Protocol)简称用户数据报协议,它是无连接的、不可靠的网络传输协议
udp网络传输协议好比运输
1.2UDP特点
因为udp发送数据之前不需要建立连接所有具有以下特点
- 无连接
- 资源开销小
- 传输速度快
- udp每个数据包最大是64K
1.3UDP的优缺点
优点:
- 传输速度快
- 不需要连接,资源开销小
缺点:
- 传输数据不可靠,容易丢数据包
- 没有流量控制,当对方没有及时接收数据,发送方一直发送数据会导致缓冲区数据满了,电脑出现卡死情况,所有接收方需要及时接收数据。
1.4UDP的使用场景
当对网络通讯质量要求不高的时候,要求网络通讯速度能尽量的快,这时就可以使用UDP
- qq音视频传输,微信音视频传输
- 上课使用的共屏软件
- 发送广播消息
小结
UDP是一个简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快
2、socket介绍
2.1不同电脑上的进程之间如何通信
首先通过ip地址找到网络中对应的电脑,然后通过传输协议和端口号来确定这个进程(运行起来的软件),那么数据如何传输需要使用socket来完成,也就是进程之间通信使用socket
注意:
所谓进程指的是:运行的程序或者软件称之为进程(在讲解多任务编程时进行详细讲解)
所谓进程间通信指的是:运行的程序之间的数据共享
2.2什么是socket
socket(简称 套接字) 是进程间通信一个工具,它能实现把数据从一方传输到另外一方,完成不同电脑上进程之间的通信, 它好比数据的搬运工。
2.3socket使用场景
不夸张来说,只要跟网络相关的应用程序或者软件都使用到了socket
3、udp网络程序-发送、接收数据
3.1udp网络程序流程
创建一个基于udp的网络程序流程很简单,具体步骤如下:
- 创建客户端套接字
- 发送/接收数据
- 关闭套接字
3.2创建socket
在 Python 中 使用socket 模块的函数 socket 就可以完成:
import socket
socket.socket(AddressFamily, Type)
说明:
函数 socket.socket 创建一个 socket,该函数带有两个参数:
Address Family:IP地址类型; AF_INET表示ipv4类型、AF_INET6表示ipv6类型; Type:套接字类型,可以是 SOCK_STREAM(流式套接字,主要用于 TCP 协议)或者 SOCK_DGRAM(数据报套接字,主要用于 UDP 协议)
创建一个udp socket(udp套接字)
import socket
# 创建udp的套接字
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# ...这里是使用套接字的功能(省略)...
# 不用的时候,关闭套接字
s.close()
说明
套接字使用流程 与 文件的使用流程很类似 创建套接字 使用套接字收/发数据 关闭套接字
3.3发送数据
代码如下:
# -*- coding: utf-8 -*-
import socket
# 1. 创建udp套接字
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 2. 准备接收方的地址 '127.0.0.1'表示目的ip地址 8080表示目的端口
dest_addr = ('127.0.0.1', 8080) # 注意 是元组,ip是字符串,端口是数字
# 3. 从键盘获取数据
send_data = input("请输入要发送的数据:")
# 4. 发送数据到指定的电脑上的指定程序中
udp_socket.sendto(send_data.encode('gbk'), dest_addr)
# 5. 关闭套接字
udp_socket.close()
在windows中运行“网络调试助手”:
3.4发送、接收数据
import socket
# 1. 创建udp套接字
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 2. 准备接收方的地址
dest_addr = ('127.0.0.1', 8080)
# 3. 从键盘获取数据
send_data = input("请输入要发送的数据:")
# 4. 发送数据到指定的电脑上
udp_socket.sendto(send_data.encode('gbk'), dest_addr)
# 5. 等待接收对方发送的数据
recv_data = udp_socket.recvfrom(1024) # 1024表示本次接收的最大字节数
# 6. 显示对方发送的数据
# 接收到的数据recv_data是一个元组
# 第1个元素是对方发送的数据
# 第2个元素是对方的ip和端口
print(recv_data[0].decode('gbk'))
print(recv_data[1])
# 7. 关闭套接字
udp_socket.close()
4、udp绑定端口号
4.1udp网络程序-端口号问题
- 会变的端口号
重新运行多次脚本,然后在“网络调试助手”中,看到的现象如下:
说明:
- 每重新运行一次网络程序,上图中红圈中的数字,不一样的原因在于,这个数字标识这个网络程序,当重新运行时,如果没有确定到底用哪个,系统默认会随机分配
- 记住一点:这个网络程序在运行的过程中,这个就唯一标识这个程序,所以如果其他电脑上的网络程序如果想要向此程序发送数据,那么就需要向这个数字(即端口号)标识的程序发送即可
4.2udp绑定信息
<1>. 绑定信息
一般情况下,在一台电脑上运行的网络程序有很多,为了不与其他的网络程序占用同一个端口号,往往在编程中,udp的端口号一般不绑定
但是如果需要做成一个服务器端的程序的话,是需要绑定的,想想看这又是为什么呢?
如果报警电话每天都在变,想必世界就会乱了,所以一般服务性的程序,往往需要一个固定的端口号,这就是所谓的端口号绑定
<2>. 绑定示例
#coding=utf-8
from socket import *
# 1. 创建套接字
udp_socket = socket(AF_INET, SOCK_DGRAM)
# 2. 绑定本地的相关信息,如果一个网络程序不绑定,则系统会随机分配
local_addr = ('127.0.0.1', 9090) # ip地址和端口号,ip一般不用写,表示本机的任何一个ip
udp_socket.bind(local_addr)
# 3. 等待接收对方发送的数据
recv_data = udp_socket.recvfrom(1024) # 1024表示本次接收的最大字节数
# 4. 显示接收到的数据
print(recv_data[0].decode('gbk'))
# 5. 关闭套接字
udp_socket.close()
运行结果:
<3>. 总结
- 一个udp网络程序,不绑定端口号,此时操作系统会随机分配一个端口号,如果绑定端口号,每次启动程序端口号不变。
结语
文章篇幅较长,给看到这里的小伙伴点个大大的赞!由于作者水平有限,文章中难免会有错误之处,欢迎小伙伴们反馈指正。
如果觉得文章对你有帮助,麻烦 点赞、评论、收藏
你的支持是我最大的动力!!!