UDP编程与Socket

文章目录

  • UDP编程与Socket
    • UDP服务端编程
    • 练习--UDP版本群聊
    • UDP协议的应用
  • 相关测试命令

    1. windows查找udp是否启动端口:

      • netstart -anp udp | find "9999"
      • netstart -anbp udp | findstr 9999
    2. linux下发给服务端数据
      • echo "123abc" | nc -u 172.0.0.1 9999

UDP服务端编程

  • UDP服务端编程流程
  1. 创建socket对象。socket.SOCK_DGRAM
  2. 绑定IP和Port,bind()方法
  3. 传输数据
    • 接收数据,socket.recvfrom(bufsize[,flags]),获得一个二元组(string,address)
    • 发送数据,socket.sendto(string,address)发给某地址某信息
  4. 释放资源
import logging
import sys
import socketlogging.basicConfig(format="%(asctime)s %(threadName)s %(thread)d %(message)s",stream=sys.stdout,level=logging.INFO)server = socket.socket(type=socket.SOCK_DGRAM) #创建一个基于UDP的socket
server.bind(("127.0.0.1",3999)) #立即绑定一个udp端口
# data = server.recv(1024) #阻塞等待数据
data,radde = server.recvfrom(1024) #阻塞等待数据(value,(ip,port))
logging.info("{}-{}".format(radde,data))
server.sendto("{} server msg = {}".format(server.getsockname(),data).encode(),radde)
server.close()
  • UDP客户端编写流程

    1. 创建socket对象。socket.SOCK_DGRAM
    2. 发送数据,socket_sendto(string,address)发给某地址信息
    3. 接收数据,socket.recvfrom(bufsize[,flags]),获得一个二元组(string,address)
    4. 释放资源
  • 第一个版本

import logging
import sys
import socketlogging.basicConfig(format="%(asctime)s %(threadName)s %(thread)d %(message)s",stream=sys.stdout,level=logging.INFO)client = socket.socket(type=socket.SOCK_DGRAM)
raddr = "127.0.0.1",3999
client.connect(raddr) #connect方法会自动分配一个本地的UDP地址,和设置UDP的链接对象raddr地址
logging.info(client)
client.send(b"hello") #由于使用了connect方法,所以不指定终端也能发送
client.sendto(b"why",raddr) #也可以使用指定地址发送
data,radde = client.recvfrom(1024)
logging.info("{}-{}".format(radde,data))
client.close()

  • 第二个版本,不使用connect指定目标
import logging
import sys
import socketlogging.basicConfig(format="%(asctime)s %(threadName)s %(thread)d %(message)s",stream=sys.stdout,level=logging.INFO)client = socket.socket(type=socket.SOCK_DGRAM)
raddr = "127.0.0.1",3999
client.sendto(b"hello",raddr)
logging.info(client)
data,laddr = client.recvfrom(1024)
logging.info("{}-{}".format(data,laddr))
client.close()

  • 注意:UDP是无链接协议,所以可以只有任何一端,例如客户端数据发往服务端,服务端存在与否无所谓。
  • UDP编程中bind、connect、send、sendto、recv、recvfrom方法使用
  • UDP的socket对象创建后,是没有占用本地地址和端口的。
方法 说明
bind(laddr) 可以指定本地地址和端口laddr,会立即占用,laddr为一个元组,(ip,prot)
connect(raddr) 会随机分配一个本地的端口laddr,会绑定远端地址和端口raddr,raddr是个元组,(ip,prot)
sendto(msg,raddr) 可以立即占用本地地址和端口laddr,并把数据发往指定远端。只有有了本地绑定的端口,sendto就可以向任何远端发送数据
msg #要发送的数据。bytes类型。
raddr#远端地址和端口组成的一个元组(ip,prot)
send(msg) 需要和connect方法配合,可以使用已经从本地端口把数据发往raddr指定的远端
msg#需要发送的消息bytes类型
recv(buffersize) 要求一定要在占用了本地端口后,返回接受的数据,buffersize指定一个缓冲区大小
recvfrom(buffersize) 要求一定要占用了本地端口后,返回接收的数据和对端地址的二元组(msg,raddr)
buffersize指定一个缓冲区大小。

练习–UDP版本群聊

  • 服务端代码
"""
author:xdd
date:2019-06-17 09:20
"""
import logging
import sys
import socket
import threading
import datetimelogging.basicConfig(format="%(asctime)s %(threadName)s %(thread)d %(message)s",stream=sys.stdout,level=logging.INFO)class ChatUDPServer:def __init__(self,ip="127.0.0.1",port=3999,timeout=10):self.socket = socket.socket(type = socket.SOCK_DGRAM)self.laddr = ip,portself.event = threading.Event()self.timeout = timeoutself.clients = {}def start(self):socket = self.socketsocket.bind(self.laddr)threading.Thread(target=self.run,name="run").start()def run(self):socket = self.socketclients = self.clientswhile not self.event.is_set():try:data,raddr = socket.recvfrom(1024)except:continueutctime = datetime.datetime.now().timestamp()if data.strip() == b"by": #如果用户自己发送by表示要退出self.clients.pop(raddr)continueclients[raddr] = utctimeif data.strip() == b"^hh^": #如果是心跳,就忽略continuemsg = "[{}] {}".format(raddr,data)logging.info(msg)outclient = [] #记录超时的链接地址for cr,tm in clients.items():if 0 <= utctime - tm <= self.timeout:socket.sendto(msg.encode(),cr)else:outclient.append(cr)for cr in outclient: #超时后删除self.clients.pop(cr)def stop(self):try:self.event.set()self.socket.close()finally:self.clients.clear()@classmethoddef main(cls):chserver = cls()chserver.start()while True:cmd = input(">>>>")if cmd.strip() == "quit":chserver.stop()threading.Event().wait(1)breaklogging.info(threading.enumerate())logging.info(chserver.clients)ChatUDPServer.main()
  • UDP版本客户端代码
"""
author:xdd
date:2019-06-17 10:26
"""import logging
import sys
import socket
import threadinglogging.basicConfig(format="%(asctime)s %(thread)d %(threadName)s %(message)s",stream=sys.stdout,level=logging.INFO)class UdpClient:def __init__(self,ip="127.0.0.1",prost = 3999,heartbeattime = 5):self.socket = socket.socket(type=socket.SOCK_DGRAM)self.raddr = ip,prostself.event = threading.Event()self.heartbeattime = heartbeattimedef start(self):self.socket.connect(self.raddr)self.send("hello")threading.Thread(target=self.heartbeat,name="heartbeat").start()threading.Thread(target=self.run,name="client").start()#发送心跳包,保持链接def heartbeat(self):while not self.event.wait(self.heartbeattime):self.send("^hh^")logging.info("心跳结束")def run(self):while not self.event.is_set():try:data,raddr = self.socket.recvfrom(1024)except:continuelogging.info("[ {} msg ] {}".format(raddr,data))def send(self,msg):#发送消息socket = self.socketsocket.send(msg.encode())def stop(self):#停止self.event.set()self.socket.close()@classmethoddef main(cls):client = cls()client.start()while True:cmd = input(">>>")if cmd.strip() == "quit":client.stop()breakelse:client.send(cmd)UdpClient.main()
  1. 服务端代码

    • 增加心跳heartbeat机制或ack机制。这些机制同样可以用在TCP通信的时候。
    • 心跳,就是一端定时发往另一端的信息,一般每次数据越少越好。心跳时间间隔约定好就行。
    • ack即响应,一端收到另一端的消息后返回的确认信息。
  • 心跳机制

    1. 一般来说是客户端定时发往服务端的,服务端并不需要ack回复客户端,只需要记录该客户端还活着就行了。
    2. 如果是服务端定时发往客户端的,一般需要客户端ack响应来表示活着,如果没有收到ack的客户端,服务端 移除其信息。这种实现较为复杂,用的较少。
    3. 也可以双向都发心跳的,用的更少。

UDP协议的应用

  • UDP是无连接协议,它基于以下假设:

    1. 网络足够好
    2. 消息不会丢包
    3. 包不会乱序
  • 但是,即使是在局域网,也不能保证不丢包,而且包的到达不一定有序。
  • 应用场景
    1. 视频、音频传输,一般来说,丢些包,问题不大,最多丢些图像、听不清话语,可以重新发话语来解决。 海量采集数据,例如传感器发来的数据,丢几十、几百条数据也没有关系。
    2. DNS协议,数据内容小,一个包就能查询到结果,不存在乱序,丢包,重新请求解析。
  • 一般来说,UDP性能优于TCP,但是可靠性要求高的场合的还是要选择TCP协议。

UDP编程与Socket相关推荐

  1. Java刷题知识点之TCP、UDP、TCP和UDP的区别、socket、TCP编程的客户端一般步骤、TCP编程的服务器端一般步骤、UDP编程的客户端一般步骤、UDP编程的服务器端一般步骤...

    TCP和UDP是两个传输层协议,广泛应用于网络中不同主机之间传输数据.对任何程序员来说,熟悉TCP和UDP的工作方式都是至关重要的.这就是为什么TCP和UDP是一个流行的Java编程面试问题. Jav ...

  2. 基于UDP协议的socket套接字编程 基于socketserver实现并发的socket编程

    基于UDP协议 的socket套接字编程 1.UDP套接字简单示例 1.1服务端 import socketserver = socket.socket(socket.AF_INET,socket.S ...

  3. python的基础网络编程是下列_Python入门基础之网络编程、socket编程、TCP、UDP编程...

    忙了两天,继续更文!希望多多支持. 套接字 套接字是一种具有之前所说的"通讯端点"概念的计算机网络数据结构.网络化的应用程序在开始任何通讯之前都必需要创建套接字. 套接字有三种: ...

  4. Socket编程实践(12) --UDP编程基础

    UDP特点 无连接,面向数据报(基于消息,不会粘包)的数据传输服务; 不可靠(可能会丢包, 乱序, 重复), 但因此一般情况下UDP更加高效; UDP客户/服务器模型 UDP-API使用 #inclu ...

  5. TCP与UDP协议,socket套接字编程,通信相关操作

    文章目录 TCP与UDP协议 TCP协议 ==三次握手== ==四次挥手== UDP协议 TCP与UDP的区别 应用层 socket套接字 代码优化 循环通信 半连接池 粘包问题 TCP与UDP协议 ...

  6. 【Linux Socket 编程入门】06 - 拉个骡子溜溜:UDP编程模型代码分析

    (一) 前情 在第4篇里面,介绍了TCP编程实例,现在,我们再看看UDP编程实例.才完美嘛. (二)上个菜:一个UDP程序分析 开胃:UDP客户服务器编程模型 与TCP面向连接,可靠的编程模型不同,U ...

  7. 网络编程基础socket 重要中:TCP/UDP/七层协议

    计算机网络的发展及基础网络概念 问题:网络到底是什么?计算机之间是如何通信的? 早期 : 联机 以太网 : 局域网与交换机 广播 主机之间"一对所有"的通讯模式,网络对其中每一台主 ...

  8. python udp socket 缓冲区大小_Python网络编程(socket模块、缓冲区、http协议)

    网络的概念:主机   端口  IP  协议 服务器: localhost/127.0.0.1 客户端: 只是在本机启动客户端,用127.0.0.1访问 服务器: 0.0.0.0 客户端: 可以在本机用 ...

  9. Sockey编程之基于 UDP 协议的 Socket 编程

    一.基于 UDP 协议的 Socket 编程 1.端口选择 已知端口:0~1023,为固定服务保留. 已注册的端口:1024~49151,供普通用户的普通用户进程或程序使用. 动态或私用端口: 491 ...

  10. vc 网络编程(socket)TCP/UDP 介绍

    在网上找了很多的资料,现将这些资料整合起来,详细介绍一下VC下的socket编程,并提供一个服务器客户端具体的实例.希望对您有所帮助 一.原理部分 在网络编程中最常用的方案便是Client/Serve ...

最新文章

  1. DataGridView使用小结
  2. C#中将list使用ProtoBuf进行序列化并使用SharpZipLib进行压缩
  3. 什么是 Linux 安全基线?
  4. 关系查询处理 查询优化 论文_2019年4月湖北自考成绩查询入口已开通
  5. java 取商_Java读取word文档,转换为网页
  6. hdu3397 线段树 成段更新
  7. window_redis
  8. 【业务安全-04】万能用户名及万能密码实验
  9. oauth2+JWT实现oauth2服务
  10. 2016年江苏省普通高等学校第十三届高等数学竞赛试题(本科一级)讲解
  11. 阿尔弗雷德.爱因斯坦论莫扎特钢协
  12. ROS系统下完成TCP通信 C语言编程
  13. 基于yolov5-6.0版本的PCB板缺陷检测(Python/C++部署)
  14. Quill编辑器介绍及扩展
  15. CG资源网站(持续更新)
  16. 【8.8】代码源 - 【不降子数组游戏】【最长上升子序列计数(Bonus)】【子串(数据加强版)】
  17. vm12创建虚拟机(nat模式)
  18. wps中自动识别目录之后打开大纲目录会出现上半部分有空白
  19. C#学习之路之使用windows media player 实例
  20. 《PMBOK 指南第七版》初识

热门文章

  1. CFA - Ethical Professional Standards 职业伦理道德
  2. ProE/Creo8.0学习笔记(更新中)
  3. 手术导航系统原理简介、主要工作及应用
  4. 桌面客户端上登入Gmai 邮箱
  5. matlab最速下降法例子,matlab 最速下降法 steepest descent (实例并附有详细说明)
  6. 字符常量与字符串常量
  7. 使用Origin绘制折线图(入门)
  8. python qq协议_利用webqq协议使用python登录qq发消息 | 学步园
  9. 互联网电商都是怎么用工厂模式的?
  10. 关闭Dynamipsgui的自动更新