脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|shell|

服务器之家 - 脚本之家 - Python - 使用python实现UDP通信方式

使用python实现UDP通信方式

2023-02-07 11:42skye_fly Python

这篇文章主要介绍了使用python实现UDP通信方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

python UDP通信

1.打开虚拟通信程序,选择UDP通信并选定收发数据的ip地址port端口

使用python实现UDP通信方式

2.在虚拟机中编写python程序与主机中的虚拟通信程序实现数据传输:

#  注释的标注格式为:每行开头则直接输入#并空一格开始注释
#  若在每行代码后面加注释,则空两格输入#再空一格开始注释
import socket
#  使用udp收发数据
def main():
	#  1.创建socket套接字
	udp_socket = socket.socket(socket.AF_INET, sock.SOCK_DGRAM)  # AF_INET表示使用ipv4,默认不变,SOCK_DGRAM表示使用UDP通信协议
	
	#  2.绑定端口port
	local_addr = ("", 7878)  # 默认本机任何ip ,指定端口号7878
	udp_socket.bind(local_addr)  # 绑定端口
	
	#  3.收发数据
	send_data = input("请输入您想要发送的数据:" )
	udp_socket.sendto(send_data.encode("utf-8"), ("10.80.34.68", 8080))  # 编码成全球统一数据格式,用元组表示接收方ip和port
	recv_data = udp_socket.recvfrom(1024)  # 定义单次最大接收字节数
	
	#  4.打印数据
	recv_msg = recv_data[0]  # 接收的元组形式的数据有两个元素,第一个为发送信息
	send_addr = recv_data[1]  # 元组第二个元素为发信息方的ip以及port
	print ("收到的信息为:", recv_msg.decode("gbk"))  # 默认从windows发出的数据解码要用”gbk”,保证中文不乱码
	print ("发送方地址为:", str(send_addr))  # 强转为字符串输出地址,保证不乱码
	
	#  5.关闭套接字
	udp_socket.close()
if __name__ == "__main__":
main()

 

对UDP协议的理解

Socket简介

网络中进程之间如何通信

1,在本地可以通过进程PID来唯一标识一个进程,但是在网络中这是行不通的。

2,TCP/IP协议族已经帮我们解决了这个问题,即:网络层的ip地址可以唯一标识网络中的主机;而传输层的:协议+端口,可以唯一标识主机中的应用程序(进程)。

3,利用ip地址,协议,端口,就可以标识网络的进程了,网络中的进程通信就可以利用这个标识与其他进程进行交互。

什么是Socket?

socket,简称:套接字,是进程间通信的一种方式。socket与其他进程间的通信方式不同在于:它能实现不同主机间的进程间通信。例如:QQ聊天、浏览网页、收发Email等等。

创建Socket

在Python中socket模块的函数socket:

socket.socket(AddressFamily,Type)

加以说明:

函数socket.socket创建一个socket,返回一个socket。

AddressFamily:选择AF_INET用于网络中进程间通信或者AF_UNIX用于同一台机器进程间通信,实际工作中常用AF_INET。

Type:套接字类型,可以是SOCK_STREAM,流式套接字,主要用于tcp协议或者SOCK_DGRAM,数据报套接字,主要用于udp协议。

#import socket
# udp:sock_dgram:数据报套接字
# udpSocket = socket(socket.AF_INET, socket.SOCK_DGRAM)
#
#
# tcp:sock_stream:流式套接字
# tcpSocket = socket(AF_INET, SOCK_STREAM)

UDP特点

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

UDP:是一种面向无连接的协议,每个数据报都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的

UDP是面向无连接的通讯协议,UDP数据包括目的端口号和源端口号信息,由于通讯不需要连接,所以可以实现广播发送。

UDP传输数据时有大小限制,每个被传输的数据报必须限定在64KB之内。

UDP是一个不可靠的协议,发送方所发送的数据报并不一定以相同的次序到达接收方。

UDP一般用于多点通信和实时的数据业务。例如:语音广播、QQ、视频会议系统等。

UDP中客户端和服务器端交互

UDP中客户端和服务器端交互

使用python实现UDP通信方式

服务器端具体实现代码如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author  : xiaoke
import socket
# 服务端
def main():
  # 1,创建数据报套接字
  udpSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  # 2,绑定本地地址,核心是为绑定并公布端口
  # ''表示指定任意ip:0.0.0.0,系统中任意ip的数据都可以接收
  myAddr = ('', 8080)
  udpSocket.bind(myAddr)
  # 3,接收客户端数据,获得客户端的地址(ip和端口号)
  recData, clientAddr = udpSocket.recvfrom(1024)
  print(clientAddr)
  print(recData.decode())
  # 4,回复客户端消息
  udpSocket.sendto(recData, clientAddr)
  # 5,关闭socket
  udpSocket.close()
if __name__ == '__main__':
  main()

echo服务器端具体实现代码如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author  : xiaoke
import socket
# echo服务端,回射服务器,发过来,弹回去
# 单进程单线程,无连接
def main():
  # 1,创建数据报套接字
  udpSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  # 2,服务端需要绑定:目的是把端口号和ip地址暴露给别人,让别人调用
  # 表示指定任意ip:0.0.0.0,系统中任意ip的数据都可以接收
  myAddr = ('', 8080)
  udpSocket.bind(myAddr)
  while True:
      # 3,接收客户端数据,获得客户端的地址(ip和端口号)
      recData, clientAddr = udpSocket.recvfrom(1024)
      # print(clientAddr)
      print(recData.decode())
      # 4,回复客户端消息
      # udpSocket.sendto(recData, clientAddr)
      sendData = input("服务器!请输入提供的数据:")
      udpSocket.sendto(sendData.encode(), clientAddr)
  # 5,关闭socket
  udpSocket.close()
if __name__ == '__main__':
  main()

客户端具体实现代码如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author  : xiaoke
import socket
# 客户端
def main():
  # 1,创建udp类型的socket
  udpSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  # 2,指定目的地址(ip和端口号
  serverAddr = ('192.168.105.125', 8080)
  while True:
      # 3,发送数据
      sendData = input("客户端!请输入请求数据:")
      udpSocket.sendto(sendData.encode(), serverAddr)
      # 4,接收数据是一个元组,本次接收数据的最大长度,建议是2^xxx次方
      receData, peerAddr = udpSocket.recvfrom(1024)
      print(receData.decode())
      # print(peerAddr)
  # 5,关闭socket
  udpSocket.close()
if __name__ == '__main__':
  main()

绑定端口的说明:

1,一般情况下,在电脑上运行的网络程序有很多,而各自用的端口号很多情况下不知道,为了不与其他的网络程序占用同一个端口号,往往在编程中,udp的端口号一般不绑定。但是如果需要做成一个服务器端的程序的话,是需要绑定的。

2,一个udp网络程序,可以不绑定端口,此时操作系统会随机进行分配一个端口,如果重新运行此程序,端口可能会发生变化。

3,一个udp网络程序,也可以绑定信息(ip地址,端口号),如果绑定成功,那么操作系统用这个端口号来进行区分收到的网络数据是否是此进程的。

UDP网络通信过程

使用python实现UDP通信方式

多线程聊天室服务器端的实现

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author  : xiaoke
import socket
from threading import Thread
def task_recv(s):
  while True:
      recvData, peerAddr = s.recvfrom(1024)
      print('子线程接收:ip地址 %s :  消息 %s' % (str(peerAddr), recvData.decode()))
def task_send(s, addr):
  while True:
      sendData = input('亲!请提供返回的数据:')
      s.sendto(sendData.encode(), addr)
def main():
  # 1.创建udp数据报套接字
  serverSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  # 2.绑定本地地址,核心是为绑定并公布端口
  myAddr = ('', 8080)  # ''表示指定任意ip 0.0.0.0 系统中任意ip的数据都可以接收
  serverSocket.bind(myAddr)
  # 3.主线程收到消息,获得对方的ip,port
  recvData, peerAddr = serverSocket.recvfrom(1024)
  print('主线程接收:ip地址 %s :  消息 %s' % (str(peerAddr), recvData.decode()))
  # 4.启动接收消息线程
  thread_recv = Thread(target=task_recv, args=(serverSocket,))
  thread_recv.start()
  # 5.再启动发送消息的线程,传递对方的ip port
  thread_send = Thread(target=task_send, args=(serverSocket, peerAddr))
  thread_send.start()
  # 6,等待子线程结束
  thread_recv.join()
  thread_send.join()
if __name__ == "__main__":
  main()

UDP中广播

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author  : xiaoke
from socket import *
def main():
  # 1,创建socket,数据报套接字
  udp_socket = socket(AF_INET, SOCK_DGRAM)
  # 2,设置允许广播
  # 设置socket属性,是否允许广播,1就是允许
  udp_socket.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
  # 3,指定广播地址(“broadcast”,2425)
  broadcast_addr = ('<broadcast>', 8080)
  # 4,发送消息,以下以飞秋软件演示
  send_data = b'1:100:will:will-pc:32:will broadcast'
  udp_socket.sendto(send_data, broadcast_addr)
  udp_socket.close()
if __name__ == '__main__':
  main()

以上为个人经验,希望能给大家一个参考,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/skye_fly/article/details/108645935

延伸 · 阅读

精彩推荐
  • PythonPython标准库之多进程(multiprocessing包)介绍

    Python标准库之多进程(multiprocessing包)介绍

    这篇文章主要介绍了Python标准库之多进程(multiprocessing包)介绍,本文讲解了进程池、共享资源、共享内存、Manager等内容,需要的朋友可以参考下 ...

    脚本之家5312020-05-15
  • Python在Python web中实现验证码图片代码分享

    在Python web中实现验证码图片代码分享

    这篇文章主要介绍了在Python web中实现验证码图片代码分享,具有一定参考价值,需要的朋友可以了解下。...

    深海不寂莫5412020-12-16
  • PythonPython程序中设置HTTP代理

    Python程序中设置HTTP代理

    本文主要给大家简单讲解了下http代理的概念以及如何在Python程序中设置http代理的方法,非常的详细,有需要的小伙伴可以参考下...

    jackyspy31502020-09-12
  • Pythonconda虚拟环境默认路径的修改方法

    conda虚拟环境默认路径的修改方法

    最近发现我linux系统中的/dev/root目录利用率占用了100%,这对后面文件的操作带来了一些麻烦,下面这篇文章主要给大家介绍了关于conda虚拟环境默认路径的修改...

    偶然is6172022-07-20
  • Pythonpython通过Seq2Seq实现闲聊机器人

    python通过Seq2Seq实现闲聊机器人

    这篇文章主要介绍了python通过Seq2Seq实现闲聊机器人,文中有非常详细的代码示例,对正在学习python的小伙伴们有很好的帮助,需要的朋友可以参考下...

    IT之一小佬11832021-10-16
  • Pythonpython使用chardet判断字符串编码的方法

    python使用chardet判断字符串编码的方法

    这篇文章主要介绍了python使用chardet判断字符串编码的方法,涉及Python编码的技巧,具有一定参考借鉴价值,需要的朋友可以参考下 ...

    liuli12052019-11-27
  • Pythonpython中对正则表达式re包的简单引用方式

    python中对正则表达式re包的简单引用方式

    这篇文章主要介绍了python中对正则表达式re包的简单引用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...

    solitary_w11472022-09-16
  • Python一篇文章教会你Python访问限制那些事儿

    一篇文章教会你Python访问限制那些事儿

    本文基于Python基础。介绍了在类中,变量访问限制。通过案例的分析,在实际应用需要注意的点,遇到的问题,提供有效的解决方案。...

    Go语言进阶学习7962021-02-24