python网络编程udp(基础篇十一)

一 网络编程udp

1 计算机网络概述

计算机网络, 是指将地理位置不同的具有独立功能的多台计算机及其外部设备, 通过通信线路连接起来, 实现资源共享和信息传递的计算机系统.

简言之, 一些相互连接的、以共享资源为目的、自治的计算机的集合.

思考: 我们现在生活可以离开网络吗?

显然是不可能的, 查询信息,社交沟通都需要建立在网络的基础上. 我们需要编写基于网络的程序. 通俗来说就是能够进行网络编程, 开发网络通信程序或者软件
在这里插入图片描述

2 IP地址

<1>IP地址的作用

IP 地址是指互联网协议地址(英语:Internet Protocol Address,又译为网际协议地址), 是 IP Address 的缩写. IP 地址是 IP 协议提供的一种统一的地址格式.

IP 地址被用来给 Internet 上的电脑一个编号。大家日常见到的情况是每台联网的 PC 上都需要有 IP 地址, 才能正常通信。我们可以把 “个人电脑” 比作 “一台电话”,那么 “IP地址” 就相当于 “电话号码”.

IP 地址是标识网络中唯一的一台设备. 每个要进行网络通信的设备, 它的 IP 地址是不一样的. IP 地址通常表现为4个数字, 并且数字以点隔开. 每个点隔开的数字都是 0-255 之间.

<2> IP地址的操作

我们可以通过 ifconfig 命令来查看和配置网卡的 IP 地址.

ifconfig查看网卡的信息:

<3> 检查网络连通性

  1. ping 127.0.0.1 检查本机操作系统网络功能工作是否正常.
  2. ping 本机网卡IP地址 检查网卡是否正常工作.
  3. ping 远程主机IP/域名 检查与远程主机的连通性

3 端口

<1> 端口作用

端口是操作系统分配给网络应用程序的编号, 当接收到数据之后, 操作系统会根据编号来将数据转发到对应编号的应用程序

<2> 端口号

端口号就是标识端口的一个编号. 在 Linux 系统中, 端口号在 0-65535 之间. 端口号不是随意使用的, 而是按照一定的规定(操作系统规定)进行分配. 端口号分:

  1. 知名端口号.
  2. 动态端口号.

网络通信的流程先通过 IP 地址找到网络中的设备, 再通过网络端口号来找到对应的程序端口, 然后通过端口把数据传输给对应的应用程序.

<3> 知名端口

知名端口号是系统程序使用的端口号. 知名端口范围从 0 到 1023.

  1. 80 端口分配给 HTTP 服务
  2. 22 端口分配给 SSH 服务.
  3. 21 端口分配给 FTP 服务

<4> 动态端口

动态端口号是普通程序使用的端口号. 动态端口的范围是从 1024 到 65535. 当这个程序关闭时, 同时也就释放了所占用的端口号.

<5> 查看端口

  • netstat -an | grep “:8080” 检验本机各端口的网络连接情况.
  • lsof -i [tcp/udp]:8080 列出当前系统端口所对应的程序.

提示: 如果非当前用户启动的软件, 需要添加 sudo 权限

4 UDP传输

<1> udp概述

UDP 英文全拼 (User Datagram Protocol) 简称用户数据报协议, 它是无连接的、不可靠的网络传输协议.

UDP 网络传输协议好比现实生活中写信.

<2> udp的特点

因为 UDP 发送数据之前不需要建立连接所有具有以下特点:

  1. 无连接
  2. 资源开销小
  3. 传输速度快
  4. udp每个数据包最大是64K

<3> udp的优缺点

  1. 优点:
    • 传输速度快
    • 不需要连接,资源开销小
  2. 缺点:
    • 传输数据不可靠,容易丢数据包
    • 没有流量控制,当对方没有及时接收数据,发送方一直发送数据会导致缓冲区数据满了,电脑出现卡死情况,所有接收方需要及时接收数据。

<4> udp使用场景

当对网络通讯质量要求不高的时候,要求网络通讯速度能尽量的快,这时就可以使用UDP.

  • qq音视频传输,微信音视频传输
  • 上课使用的共屏软件
  • 发送广播消息

5 socket介绍

<1> 不同电脑进程之间通信

首先通过 IP 地址找到网络中对应的电脑,然后通过传输协议和端口号来确定这个进程(运行起来的软件),那么数据如何传输需要使用 socket 来完成,也就是进程之间通信使用 socket.

什么是进程? 什么是进程间通信?

  1. 所谓进程指的是:运行的程序或者软件称之为进程(在讲解多任务编程时进行详细讲解)
  2. 所谓进程间通信指的是:运行的程序之间的数据共享

<2> 什么是socket

socket(简称 套接字) 是进程间通信一个工具,它能实现把数据从一方传输到另外一方,完成不同电脑上进程之间的通信, 它好比数据的搬运工。

<3> socket使用场景

不夸张来说,只要跟网络相关的应用程序或者软件都使用到了socket, 比如:

6 udp发送和接收数据

<1> UDP 网络程序流程

创建一个基于 UDP 的网络程序流程很简单, 具体步骤如下:

  1. 创建 UDP 套接字
  2. 发送/接收数据
  3. 关闭套接字

img

<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> 发送数据

代码如下:

import socket

# 1. 创建udp套接字
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# 2. 准备接收方的地址
# '192.168.1.103'表示目的ip地址
# 8080表示目的端口
dest_addr = ('192.168.1.103', 8080)  # 注意 是元组,ip是字符串,端口是数字

# 3. 从键盘获取数据
send_data = input("请输入要发送的数据:")

# 4. 发送数据到指定的电脑上的指定程序中
udp_socket.sendto(send_data.encode('utf-8'), dest_addr)

# 5. 关闭套接字
udp_socket.close()

在windows中运行“网络调试助手”:

网络调试助手接收数据

<4> 接收数据

import socket

# 1. 创建udp套接字
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# 2. 准备接收方的地址
dest_addr = ('192.168.236.129', 8080)

# 3. 从键盘获取数据
send_data = input("请输入要发送的数据:")

# 4. 发送数据到指定的电脑上
udp_socket.sendto(send_data.encode('utf-8'), 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()

网络调试助手截图:

网络调试助手接收数据

7 数据解码和编码

str->bytes:encode编码
bytes->str:decode解码

字符串通过编码成为字节码,字节码通过解码成为字符串。

>>> text = '我是文本'
>>> text
'我是文本'
>>> print(text)
我是文本
>>> bytesText = text.encode()
>>> bytesText
b'\xe6\x88\x91\xe6\x98\xaf\xe6\x96\x87\xe6\x9c\xac'
>>> print(bytesText)
b'\xe6\x88\x91\xe6\x98\xaf\xe6\x96\x87\xe6\x9c\xac'
>>> type(text)
<class 'str'>
>>> type(bytesText)
<class 'bytes'>
>>> textDecode = bytesText.decode()
>>> textDecode
'我是文本'
>>> print(textDecode)
我是文本

其中decode()与encode()方法可以接受参数,其声明分别为:

bytes.decode(encoding="utf-8", errors="strict")
str.encode(encoding="utf-8", errors="strict")

其中的encoding是指在解码编码过程中使用的编码格式,errors是指错误的处理方案。

注意:

  • strict:表示严格按照指定编解码方式进行编码和解码,如果编解码不成功则抛出异常
  • ignore:表示忽略编解码不成功的字符,如果编解码不成功程序不会抛出异常
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章