Pyhton socket套接字之UDP编程

易小灯塔
2017-08-11 / 0 评论 / 1,032 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2022年06月22日,已超过888天没有更新,若内容或图片失效,请留言反馈。

Pyhton的socket套接字之UDP编程

是进程间通信的一种方式,它与其他进程间通信的一个主要不同是:它能实现不同主机间的进程间通信,我们网络上各种各样的服务大多都是基于 Socket 来完成通信的。

创建socket 在 Python 中 使用socket 模块的函数 socket 就可以完成:

import socket
socket.socket(AddressFamily, Type) 

函数 socket.socket 创建一个 socket,该函数带有两个参数:

  • AddressFamily:可以选择 AF_INET(用于 Internet 进程间通信) 或者 AF_UNIX(用于同一台机器进程间通信),实际工作中常用AF_INET
  • Type:套接字类型,可以是 SOCK_STREAM(流式套接字,主要用于 TCP 协议)或者 SOCK_DGRAM(数据报套接字,主要用于 UDP 协议)

示例代码:

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  #创建udp的套接字
#s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #创建tcp的套接字

# ...这里是使用套接字的功能(省略)...

# 不用的时候,关闭套接字
s.close() 

套接字使用流程与文件的使用流程很类似:

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

UDP 不提供可靠性的传输,它只是把应用程序传给 IP 层的数据报发送出去,但是并不能保证它们能到达目的地。由于 UDP 在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快。

Pyhton socket套接字之UDP编程

对于 UDP发送方流程, 有点类似于写信过程:

  1. 找个邮政工作人员(socket())
  2. 信封上写上地址同时里面装上信件内容并且投递(sendto() )
  3. 还可以继续写信,或者,接收对方的回信(recvfrom() )
  4. 打完收工(close() )

示例代码:

import socket

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

#2、发送数据
sendData = input("请输入要发送的数据:")
udp.sendto(sendData.encode("utf-8"), ("172.16.1.52", 8080))

#3、接收数据
recvData = udp.recvfrom(1024)
print("recvData = ", recvData)

#4、关闭套接字
udp.close() 

UDP 发送方注意点

  1. 本地IP、本地端口(我是谁)
  2. 目的IP、目的端口(发给谁)
  3. 在发送方的代码中,我们只设置了目的IP、目的端口
  4. 发送方的本地 ip、本地 port 是我们调用 sendto 的时候系统底层自动给客户端分配的。分配端口的方式为随机分配,即每次运行系统给的 port 不一样。

python3编码转换

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

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是指错误的处理方案。

详细的可以参照官方文档:

元组拆包

>>> addr = ("127.0.0.1", 8888)
>>> ip, port = addr
>>> type(ip)
<class 'str'>
>>> type(port)
<class 'int'>
>>> print(ip)
127.0.0.1
>>> print(port)
8888 

示例代码:

recvData, recvAddr = udp.recvfrom(1024)
print(recvAddr, " >>>>>>>>>>>>> ", recvData.decode("utf-8")) 

接收端接收数据的条件

UDP网络程序想要收取数据需什么条件?

  1. 确定的 ip 地址
  2. 确定的端口(port)

这正如,我要收到别人寄过来的信,我必须告诉别人我的地址(ip),同时告诉别人我我的公寓信箱号(端口)。

接收端使用 bind() 函数,来完成地址结构与 socket 套接字的绑定,这样 ip、port 就固定了,发送端在 sendto 函数中指定接收端的 ip、port,就可以发送数据了。

2.3.4.2 示例代码

对于 UDP 服务器编程流程, 有点类似于收信过程:

  1. 找个邮政工作人员( socket() )
  2. 确定信箱的位置:地址+信箱号(bind() )
  3. 等待对方的来信( recvfrom() )
  4. 还可以回信(sendto() ),或者,继续等待对方的来信……
  5. 打完收工(close() )

 

image-20201107151425979

0

评论 (0)

取消