Python之socket_udp
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的更多相关文章
- Python中的多进程与多线程(一)
一.背景 最近在Azkaban的测试工作中,需要在测试环境下模拟线上的调度场景进行稳定性测试.故而重操python旧业,通过python编写脚本来构造类似线上的调度场景.在脚本编写过程中,碰到这样一个 ...
- Python高手之路【六】python基础之字符串格式化
Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...
- Python 小而美的函数
python提供了一些有趣且实用的函数,如any all zip,这些函数能够大幅简化我们得代码,可以更优雅的处理可迭代的对象,同时使用的时候也得注意一些情况 any any(iterable) ...
- JavaScript之父Brendan Eich,Clojure 创建者Rich Hickey,Python创建者Van Rossum等编程大牛对程序员的职业建议
软件开发是现时很火的职业.据美国劳动局发布的一项统计数据显示,从2014年至2024年,美国就业市场对开发人员的需求量将增长17%,而这个增长率比起所有职业的平均需求量高出了7%.很多人年轻人会选择编 ...
- 可爱的豆子——使用Beans思想让Python代码更易维护
title: 可爱的豆子--使用Beans思想让Python代码更易维护 toc: false comments: true date: 2016-06-19 21:43:33 tags: [Pyth ...
- 使用Python保存屏幕截图(不使用PIL)
起因 在极客学院讲授<使用Python编写远程控制程序>的课程中,涉及到查看被控制电脑屏幕截图的功能. 如果使用PIL,这个需求只需要三行代码: from PIL import Image ...
- Python编码记录
字节流和字符串 当使用Python定义一个字符串时,实际会存储一个字节串: "abc"--[97][98][99] python2.x默认会把所有的字符串当做ASCII码来对待,但 ...
- Apache执行Python脚本
由于经常需要到服务器上执行些命令,有些命令懒得敲,就准备写点脚本直接浏览器调用就好了,比如这样: 因为线上有现成的Apache,就直接放它里面了,当然访问安全要设置,我似乎别的随笔里写了安全问题,这里 ...
- python开发编译器
引言 最近刚刚用python写完了一个解析protobuf文件的简单编译器,深感ply实现词法分析和语法分析的简洁方便.乘着余热未过,头脑清醒,记下一点总结和心得,方便各位pythoner参考使用. ...
随机推荐
- url传参过程中文字需编码、解码使用
1.链接进行编码跳转:window.location.href = encodeURI(url) 2.获取当前链接进行解码:decodeURI(window.location); 3.获取url中参数 ...
- Angularjs 跨域请求
不知道什么意思修改了service 参考http://blog.csdn.net/hj7jay/article/details/51767805 http://blog.csdn.net/tangsl ...
- 读取gzmt.csv文件,计算均值及概率
问题: 读取gzmt.csv文件所有数据,选取收盘价格(倒数第二列),计算20天均值,权重取成交量(选做:时间权重为半衰期为15天):将该均值修剪为超过600的都设置为1000,并打印出该均值超过55 ...
- Java数据库连接与查询
9个步骤: 1.加载数据库驱动: 2.连接数据库: 3.创建语句statement: 5.创建sql语法字符串: 6.执行: 7.如果步骤6是执行新增.修改.删除操作那么返回的是影响的行数,如果是执行 ...
- [LeetCode] Subdomain Visit Count 子域名访问量统计
A website domain like "discuss.leetcode.com" consists of various subdomains. At the top le ...
- 杂_小技巧_将网页上的内容通过亚马逊邮箱传到kindle中
所需条件 1.kindle要联网 2.要有亚马逊邮箱 3.要有微信,电脑上或者手机上 操作步骤: 1.找到你想要传送到kindle上的文章网页 2.在微信中关注“亚马逊kindle服务号”并且按照里边 ...
- 基于hortonworks的大数据集群环境部署流水
一.ambari及HDP安装文件下载地址: 1.系统 操作系统:CentOS7 2.软件 本次安装采用最新版本: ambari-2.7.0.0 hdp-3.0.0.0 详细信息及下载地址如下: Amb ...
- 新人上手:如何做好一个App的推广?
App推广是现在所有公司都绕不开的槛,而一般App推广又分为线上线下两个方面,其中,App线上推广是互联网时代运营人员接触最多的一种推广方式.一款App应用推广的最终目的是为了吸引目标用户,为推销的产 ...
- html/jsp导出pdf格式的几种方法(jsPDF,iText,wkhtmltopdf)
在许多生成报表的时候需要我们后台作出动态的数据,并渲染到前端生成pdf格式,Excel格式的各种报表,但是浏览器自带的生成pdf功能,windows系统的ctrl+p键就能完全搞定这一需求,但对客户来 ...
- GMT\UTC YYYY-MM-DDTHH:mm:ss.sssZ、YYYY-MM-DDTHH:mm:ss.sss+8:00意义及与北京时间转换
UTC: Universal Time Coordinated 协调世界时,又称世界标准时间. GMT: Greenwich Mean Time 格林尼治平均时. 格林尼治标准时间的正午是指当太阳横穿 ...