python 基于UDP协议套接字通信的实现


Posted in Python onJanuary 22, 2021

一、UPD实现单用户通信

服务端:

'''
from socket import *

server=socket(AF_INET,SOCK_DGRAM)
	- 这里代指的是一种数据报协议,数据报协议指的就是udp协议(补充: 数据报就是自己utp协议中有自己的头,有自己的数据部分)

server.bind('IP', PORT)

bytes类型的数据, client_addr = server.recvfrom(1024)
  - client_addr是一个2元组的形式: 第一个参数是客户端的IP地址, 第二个参数是客户端发送数据进程软件的端口号.

server.sendto(bytes类型处理过后的数据, client_addr)

server.close()
'''
from socket import *
server=socket(AF_INET,SOCK_DGRAM)
IP_PORT=('127.0.0.1',8123)
server.bind(IP_PORT)
while True:
  print("server wait...")
  data_bytes,client_addr=server.recvfrom(1024)
  server.sendto(data_bytes.upper(),client_addr)
  print('data_bytes:', data_bytes)
  print('client_addr:', client_addr)
server.close()

客户端:

'''
from socket import *

client=socket(AF_INET,SOCK_DGRAM)

client.sendto(bytes类型的数据, ('服务端IP', 服务端端口))

data_bytes, client_addr = client.recvfrom(1024)

client.close()
'''
import socket

client = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
IP_PORT=('127.0.0.1',8123)
while True:
  msg=input("请输入要发送的消息》》》").strip()
  client.sendto(msg.encode("utf-8"),IP_PORT)
  data_bytes,server_addr=client.recvfrom(1024)
  print("data_bytes:",data_bytes)
  print("server_addr:",server_addr)
client.close()
  • UDP是无链接的,先启动哪一端都不会报错
  • UDP协议是数据报协议,发空的时候也会自带报头,因此客户端输入空,服务端也能收到

二、UDP普遍无粘包问题

服务端:

import socket

server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 数据报协议-》udp
server.bind(('127.0.0.1', 8084))

data, client_addr = server.recvfrom(1024) # b'hello'==>b'h'
print('第一次:', client_addr, data)

data, client_addr = server.recvfrom(1024) # b'world' =>b'world'
print('第二次:', client_addr, data)
#
data,client_addr=server.recvfrom(1024)
print('第三次:',client_addr,data)

server.close()

客户端

import socket

client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 数据报协议-》udp

client.sendto('hello'.encode('utf-8'), ('127.0.0.1', 8084))
client.sendto('world'.encode('utf-8'), ('127.0.0.1', 8084))
client.sendto(''.encode('utf-8'),('127.0.0.1',8084))

client.close()
  • UDP协议一般不用于传输大数据
  • UDP普遍虽然没有粘包问题,但是并不能替代TCP,因为UDP协议有一个缺陷:如果发送数据的途中发生数据丢失,则数据就真的丢失了,而TCP协议就不会有这种缺陷,因此一般UDP用于一些无关紧要的数据发送,例如QQ、微信聊天等…

三、总结:UDP与TCP的区别

区别一:UDP协议不会因为客户端发送的数据为空,从而导致客户端和服务端发生异常。
区别二:UDP协议服务端不会因为客户端强制断开连接,从而导致服务端发生异常

  • UDP协议叫数据报协议,什么叫数据报?报就分成头和数据两部分, 它是一个完整的整体. 它不是单纯的数据
  • 举个例子: 基于UDP协议发送的数据, 每次的发都是一个集装箱过去,并不是空的,所以,你的数据看起来是空,但是我会在数据报的基础上,对你的数据进行一个处理,所以说服务端收到的并不是空.
  • 数据报的概念: 当客户端发送的数据虽然是空,但是数据报会以一个集装箱的样子给你发送到服务端过去,因此服务端收到的,其实并不是空的数据, 服务端收到的还有客户端的Ip和端口

四、案例

1、基于UDP协议实现时间格式化服务器

服务端

from socket import *
from time import strftime

server=socket(AF_INET,SOCK_DGRAM)
server.bind(("127.0.0.1",8908))
print("server run...")
while True:
  msg,addr=server.recvfrom(1024)
  print(f"[{addr[0]}]链接成功")
  if not msg:
    fmt = "%Y-%m-%d %X"
  else:
    fmt=msg.decode("utf-8")
  time_fmt=strftime(fmt)
  server.sendto(time_fmt.encode("utf-8"),addr)

客户端

from socket import *
client=socket(AF_INET,SOCK_DGRAM)
print("输入时间格式,返回格式化后的时间")
ip_port=("127.0.0.1",8908)
while True:
  inp=input("请输入时间格式(例:%Y-%m-%d)>>>:").strip()
  client.sendto(inp.encode("utf-8"),ip_port)
  date=client.recv(1024)
  print(date.decode("utf-8"))

2、基于udp协议是实现米聊功能

注意:聊天是客户端与客户端进行的聊天,客户端把数据发送到了服务端,再有服务端转发到客户端,这样就是实现了客户端与客户端之间的的聊天。

需求:基于UDP协议是实现一个多用户通信,可回多个客户端的信息, 回完一个紧接着可回下一个, 不需要连接

服务端:

#_*_coding:utf-8_*_
__author__="淘小欣"
import socket
ip_port = ('127.0.0.1', 8081)
UDP_server_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #买手机
UDP_server_sock.bind(ip_port)
print("Server...")
while True:
  ml_msg, addr = UDP_server_sock.recvfrom(1024)
  print('来自[%s:%s]的一条消息:\033[1;44m%s\033[0m' %
     (addr[0], addr[1], ml_msg.decode('utf-8')))
  back_msg = input('回复消息: ').strip()

  UDP_server_sock.sendto(back_msg.encode('utf-8'), addr)

客户端一:

#_*_coding:utf-8_*_
__author__="淘小欣"
import socket
BUFSIZE=1024
UDP_client_socket=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
MiLiao_name_dic={
  "淘小欣":("127.0.0.1",8881),
  "shawn":("127.0.0.1",8881),
  "派大星":("127.0.0.1",8881),
  "派大星的真心话":("127.0.0.1",8881)
}
while True:

  ml_name = input('请选择聊天对象: ').strip()
  while True:
    msg = input('请输入消息,回车发送: ').strip()
    if msg == 'quit': break
    if not msg or not ml_name or ml_name not in MiLiao_name_dic: continue
    UDP_client_socket.sendto(msg.encode('utf-8'), MiLiao_name_dic[ml_name])

    back_msg, addr = UDP_client_socket.recvfrom(BUFSIZE)
    print('来自[%s:%s]的一条消息:\033[1;44m%s\033[0m' %
       (addr[0], addr[1], back_msg.decode('utf-8')))

UDP_client_socket.close()

客户端二:

#_*_coding:utf-8_*_
__author__="淘小欣"
import socket
BUFSIZE=1024
UDP_client_socket=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
MiLiao_name_dic={
  "淘小欣":("127.0.0.1",8881),
  "shawn":("127.0.0.1",8881),
  "派大星":("127.0.0.1",8881),
  "派大星的真心话":("127.0.0.1",8881)
}
while True:

  ml_name = input('请选择聊天对象: ').strip()
  while True:
    msg = input('请输入消息,回车发送: ').strip()
    if msg == 'quit': break
    if not msg or not ml_name or ml_name not in MiLiao_name_dic: continue
    UDP_client_socket.sendto(msg.encode('utf-8'), MiLiao_name_dic[ml_name])

    back_msg, addr = UDP_client_socket.recvfrom(BUFSIZE)
    print('来自[%s:%s]的一条消息:\033[1;44m%s\033[0m' %
       (addr[0], addr[1], back_msg.decode('utf-8')))

UDP_client_socket.close()

以上就是python 基于UDP协议套接字通信的实现的详细内容,更多关于python 套接字通信的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
python实现简单socket程序在两台电脑之间传输消息的方法
Mar 13 Python
python批量生成本地ip地址的方法
Mar 23 Python
在Python中利用Pandas库处理大数据的简单介绍
Apr 07 Python
Python抓取手机号归属地信息示例代码
Nov 28 Python
Python求两个圆的交点坐标或三个圆的交点坐标方法
Nov 07 Python
PyQt编程之如何在屏幕中央显示窗体的实例
Jun 18 Python
python程序中的线程操作 concurrent模块使用详解
Sep 23 Python
python 实现将Numpy数组保存为图像
Jan 09 Python
Pycharm中安装wordcloud等库失败问题及终端通过pip安装的Python库如何添加到Pycharm解释器中(推荐)
May 10 Python
pytorch中 gpu与gpu、gpu与cpu 在load时相互转化操作
May 25 Python
python属于跨平台语言码
Jun 09 Python
新手学习Python2和Python3中print不同的用法
Jun 09 Python
详解matplotlib中pyplot和面向对象两种绘图模式之间的关系
Jan 22 #Python
Jmeter调用Python脚本实现参数互相传递的实现
Jan 22 #Python
Python实现王者荣耀自动刷金币的完整步骤
Jan 22 #Python
python实现马丁策略回测3000只股票的实例代码
Jan 22 #Python
Python爬虫回测股票的实例讲解
Jan 22 #Python
python+selenium实现12306模拟登录的步骤
Jan 21 #Python
python基于爬虫+django,打造个性化API接口
Jan 21 #Python
You might like
Terran历史背景
2020/03/14 星际争霸
PHP+DBM的同学录程序(1)
2006/10/09 PHP
PHP脚本数据库功能详解(上)
2006/10/09 PHP
PHPExcel在linux环境下导出报500错误的解决方法
2017/01/26 PHP
深入浅析PHP的session反序列化漏洞问题
2017/06/15 PHP
利用PHP内置SERVER开启web服务(本地开发使用)
2021/03/09 PHP
javascript 获取select下拉列表值的代码
2009/09/07 Javascript
JQuery中对服务器控件 DropdownList, RadioButtonList, CheckboxList的操作总结
2011/06/28 Javascript
JavaScript AJAX之惰性载入函数
2014/08/27 Javascript
跟我学习javascript的基本类型和引用类型
2015/11/16 Javascript
js获取元素的外链样式的简单实现方法
2016/06/06 Javascript
Angular2管道Pipe及自定义管道格式数据用法实例分析
2017/11/29 Javascript
小程序日历控件使用方法详解
2018/12/29 Javascript
Angular封装搜索框组件操作示例
2019/04/25 Javascript
了解javascript中let和var及const关键字的区别
2019/05/24 Javascript
vue 实现Web端的定位功能 获取经纬度
2019/08/08 Javascript
keep-alive不能缓存多层级路由菜单问题解决
2020/03/10 Javascript
js调用网络摄像头的方法
2020/12/05 Javascript
python代码 if not x: 和 if x is not None: 和 if not x is None:使用介绍
2016/09/21 Python
Django读取Mysql数据并显示在前端的实例
2018/05/27 Python
解决python3 HTMLTestRunner测试报告中文乱码的问题
2018/12/17 Python
python gensim使用word2vec词向量处理中文语料的方法
2019/07/05 Python
python异步编程 使用yield from过程解析
2019/09/25 Python
利用python制作拼图小游戏的全过程
2020/12/04 Python
简单介绍HTML5中的文件导入
2015/05/08 HTML / CSS
HTML5录音实践总结(Preact)
2020/05/07 HTML / CSS
美国专注于健康商品的网站:eVitamins
2017/01/23 全球购物
最耐用行李箱,一箱永流传:Briggs & Riley(全球终身保修)
2017/12/07 全球购物
Bally澳大利亚官网:瑞士奢侈品牌
2018/11/01 全球购物
小蚁科技官方商店:YI Technology
2019/08/23 全球购物
九年级科学教学反思
2014/01/29 职场文书
经济职业学院毕业生自荐书
2014/03/17 职场文书
音乐教师个人工作总结
2015/02/06 职场文书
原告离婚代理词
2015/05/23 职场文书
如何才能写好调研报告?
2019/07/03 职场文书
如何判断微信付款码和支付宝付款码
2021/04/01 PHP