UDP服务端&客户端编程

'''
udp编程
创建socket对象,socket.SOCK_DGRAM
绑定ip和port,bind()方法
传输数据
1.接收数据,socket.recvfrom(bufsize[,flags]),获得一个2元祖(string,address)
2.发送数据,socket.sendto(string,address) ,发送给某地址信息
释放资源
'''
import socket
server = socket.socket(type=socket.SOCK_DGRAM)
server.bind(('0.0.0.0',9999))
data = server.recv(1024) #阻塞等待数据
data = server.recvfrom(1024) #阻塞等待数据(value,(ip,port))
server.sendto(b'hello',('127.0.0.1',10000))
server.close() '''
udp客户端编程流程
创建socket对象,socket.SOCK_DGRAM
发送数据,socket.sendto(string,address)发送给某地址信息
接收数据,socket.recvfrom(bufsize[,flags]),获取一个2元祖(string,address)
释放资源
'''
client = socket.socket(type=socket.SOCK_DGRAM)
raddr = ('127.0.0.1',10000)
client.connect(raddr)
client.sendto(b'hello',raddr)
data = client.recv(1024) #阻塞等待数据
data = client.recvfrom(1024)#阻塞等待数据,(value,(ip,port))
client.close()
注意:udp时无连接协议,所以可以只有任何一端,例如客户端数据发往服务端,服务端存在与否不重要
udp的socket对象创建后,时没有占用本地地址和端口的
bind() 可以指定本地地址和端口laddr,会立即占用
connect() 可以立即占用本地地址和端口,填充远端地址和端口raddr
sendto() 可以立即占用本地地址和端口,并把数据发往指定远端,只有有了本地绑定端口,sendto就可以向任何远端发送数据
send() 需要和connect()配合使用,可以使用已经从本地端口把数据发往raddr指定的远端
recv() 要求一定要在占用可本地端口后,返回接收的数据
recvfrom() 要求一定要占用了本地端口后,返回接收数据和对端地址的二元组

 udp聊天server

import threading
import socket
import logging
FORMAT = '%(asctime)s,%(threadName)s %(thread)d,%(message)s'
logging.basicConfig(level=logging.INFO,format=FORMAT) class ChatUDPServer:
def __init__(self,ip='127.0.0.1',port=9999):
self.addr = (ip,port)
self.sock = socket.socket(type=socket.SOCK_DGRAM)
self.event = threading.Event()
self.clients = set()
def start(self):
self.sock.bind(self.addr)
threading.Thread(target=self.receive,name='receive').start() def receive(self):
while not self.event.is_set():
data,raddr= self.sock.recvfrom(1024)
print(data)
if data.strip() == b'quit':
if raddr in self.clients:
self.clients.remove(raddr)
logging.info('remove leave clients')
# self.sock.close() 面向无连接的 所以每天udp产生的时候不需要close
continue
self.clients.add(raddr)
for i in self.clients:
self.sock.sendto('ack {}'.format(data).encode(),i) def stop(self):
for i in self.clients:
self.sock.sendto(b'bye bye',i)
self.sock.close()
self.event.set() def main():
cs = ChatUDPServer()
cs.start()
while True:
cmd = input("please set stop command>>>>>>")
if cmd == 'quit':
cs.stop()
break
logging.info(cs.clients)
logging.info(threading.enumerate()) if __name__ == '__main__':
main()

心跳机制:客户端定时往服务端发送的,服务端不需要ack回复,只记录客户端存活

class ChatUDPServer:
def __init__(self,ip='127.0.0.1',port=9999,interval=10):
self.addr = (ip,port)
self.sock = socket.socket(type=socket.SOCK_DGRAM)
self.event = threading.Event()
self.clients = {}
self.interval = interval
def start(self):
self.sock.bind(self.addr)
threading.Thread(target=self.receive,name='receive').start() def receive(self):
while not self.event.is_set():
localset = set()      #迭代字典时不能操作字典,把超时的放在集合里面
data,raddr= self.sock.recvfrom(1024)
current = datetime.datetime.now().timestamp() #return float
if data.strip == b'^hb^': #从client接收到指定的字符串,做判断
print('~~~~~~~~',raddr)
self.clients[raddr] = current
continue
elif data.strip() == b'quit':
if raddr in self.clients:
self.clients.pop(raddr,None)
logging.info('remove leave clients')
# self.sock.close() 面向无连接的 所以不需要close
continue
self.clients[raddr] = current
for c,stamp in self.clients.items():
if current - stamp > self.interval:
localset.add(c)
else:
self.sock.sendto('ack {}'.format(data).encode(), i)
for i in localset:    
localset.pop(i) def stop(self):
for i in self.clients:
self.sock.sendto(b'bye bye',i)
self.sock.close()
self.event.set()

client端的更改

    def start(self):
self.sock.connect(self.addr)
self.sock.sendto(b'hello server',self.addr)
threading.Thread(target=self.reveive,name='receive').start()
threading.Thread(target=self._sendb,name="heartbeat",daemon=True).start()
     #daemon 随着主线程退出而退出,不用程序员关注线程退出的问题
def _sendb(self):
while True:
self.sock.sendto(b'^hb^',self.addr)

Python之socket_udp的更多相关文章

  1. Python中的多进程与多线程(一)

    一.背景 最近在Azkaban的测试工作中,需要在测试环境下模拟线上的调度场景进行稳定性测试.故而重操python旧业,通过python编写脚本来构造类似线上的调度场景.在脚本编写过程中,碰到这样一个 ...

  2. Python高手之路【六】python基础之字符串格式化

    Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...

  3. Python 小而美的函数

    python提供了一些有趣且实用的函数,如any all zip,这些函数能够大幅简化我们得代码,可以更优雅的处理可迭代的对象,同时使用的时候也得注意一些情况   any any(iterable) ...

  4. JavaScript之父Brendan Eich,Clojure 创建者Rich Hickey,Python创建者Van Rossum等编程大牛对程序员的职业建议

    软件开发是现时很火的职业.据美国劳动局发布的一项统计数据显示,从2014年至2024年,美国就业市场对开发人员的需求量将增长17%,而这个增长率比起所有职业的平均需求量高出了7%.很多人年轻人会选择编 ...

  5. 可爱的豆子——使用Beans思想让Python代码更易维护

    title: 可爱的豆子--使用Beans思想让Python代码更易维护 toc: false comments: true date: 2016-06-19 21:43:33 tags: [Pyth ...

  6. 使用Python保存屏幕截图(不使用PIL)

    起因 在极客学院讲授<使用Python编写远程控制程序>的课程中,涉及到查看被控制电脑屏幕截图的功能. 如果使用PIL,这个需求只需要三行代码: from PIL import Image ...

  7. Python编码记录

    字节流和字符串 当使用Python定义一个字符串时,实际会存储一个字节串: "abc"--[97][98][99] python2.x默认会把所有的字符串当做ASCII码来对待,但 ...

  8. Apache执行Python脚本

    由于经常需要到服务器上执行些命令,有些命令懒得敲,就准备写点脚本直接浏览器调用就好了,比如这样: 因为线上有现成的Apache,就直接放它里面了,当然访问安全要设置,我似乎别的随笔里写了安全问题,这里 ...

  9. python开发编译器

    引言 最近刚刚用python写完了一个解析protobuf文件的简单编译器,深感ply实现词法分析和语法分析的简洁方便.乘着余热未过,头脑清醒,记下一点总结和心得,方便各位pythoner参考使用. ...

随机推荐

  1. 数字图像特征提取之HOG特征

    1.灰度化:(以便可以使用sobel等算子计算梯度)2.gamma校正: (降低光照影响)3.求每个像素的梯度和方向: (利用任意一种梯度算子,例如:sobel,laplacian等,对该patch进 ...

  2. BZOJ.5110.[CodePlus2017]Yazid 的新生舞会(线段树/树状数组/分治)

    LOJ BZOJ 洛谷 又来发良心题解啦 \(Description\) 给定一个序列\(A_i\).求有多少个子区间,满足该区间众数出现次数大于区间长度的一半. \(n\leq5\times10^5 ...

  3. Java Web 禁用Cookie对Session的影响

    如果客户端禁用了Cookie,那么服务端就不能得到Session了.因为通过Session ID来确定当前会话对应的服务端Session,而Session ID通过Cookie来传递,所以禁用Cook ...

  4. Solve fatal error: helper_math.h: No such file or directory

    When the 'fatal error: helper_math.h: No such file or directory' occurs, it means the 'helper_math.h ...

  5. 白盒测试实践-day04

    一.任务进展情况 通过小组成员的共同努力,终于完成了此次“白盒测试实践”任务.目前的主要任务将之前的文件汇总,整理出来. 二.存在的问题 由于测试系统的不完善,导致单元测试比较麻烦. 三.解决方法 认 ...

  6. python语法_集合

    集合:不同的元素(不可hash)组合在一起的就叫做集合,去掉重复的,以空字符返回,无序的 可以分为可变集合和不可变集合(frozenset) 创建: s = set('gm gyx') print(s ...

  7. c语言二级指针内存模型

    第一种: 指针数组作为输入参数 char *myArray[] = {"aaaaaa", "ccccc", "bbbbbb", " ...

  8. 利用野草weedcmsuseragent盲注漏洞拿shell

    野草网站管理系统(WEEDCMS)是由野草独立基于PHP+MYSQL开发的内容管理系统.面向企业.个人.小门户等中小规模网站使用而开发的.采用国际上比较流行Smarty引擎和敏捷的JQuery JS框 ...

  9. python字典转化成json格式。JSONEncoder和JSONDecoder两个类来实现Json字符串和dict类型数据的互相转换

    遇到问题:进行Webservice接口测试时,对接口入参数据进行了处理,变成了dict格式,去进行接口请求报错. 需要转成成json格式,双引号去扩. 如下: 更改代码: # 在Python标准库的j ...

  10. spring cloud

    如果是一个大型的网站,内部子系统较多.接口非常多的情况下,RPC框架的好处就显示出来了,首先就是长链接,不必每次通信都要像http 一样去3次握手什么的,减少了网络开销:其次就是RPC框架一般都有注册 ...