相对于TCP,Twisted中的UDP编程只需要定义DatagramProtocol子类,而无需定义Factory子类
UDP 通信没有客户端、服务器之分
DatagramProtocol
- datagramReceived():接收到UDP报文后处理的事件
# coding:utf8
import sys
from datetime import datetime
from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor
class Echo(DatagramProtocol):
def datagramReceived(self, datagram: bytes, addr):
'''
接收UDP数据事件
:param datagram: 数据(二进制)
:param addr: 发送端的地址 ,可以通过这个地址回复消息
:return:
'''
print('Got data from :%s'%(addr,))
print(datagram.decode('utf8'))
str_msg = 'hello , i am %s %s' % (sys.argv[0], datetime.now())
self.transport.write(str_msg.encode('utf8'),addr) # 回复消息
port = 8009
reactor.listenUDP(port,Echo())
reactor.run()
下例中开启一个业务线程,首先发起发送数据
# coding:utf8
import sys,threading,time
from datetime import datetime
from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor
class Echo(DatagramProtocol):
def datagramReceived(self, datagram: bytes, addr):
print('Got data from :%s'%(addr,))
print(datagram.decode('utf8'))
protocol = Echo()
host = '127.0.0.1'
port = 8008 # 监听端口
port_target = 8009
b_stop = False
def routine():
while not b_stop:
time.sleep(5)
str_msg = 'hello , i am %s %s' % (sys.argv[0], datetime.now())
protocol.transport.write(str_msg.encode('utf8'),(host,port_target))
threading.Thread(target=routine).start()
reactor.listenUDP(port,protocol)
reactor.run()
b_stop=True
Connected UDP
虽然UDP本身是无协议连接,但是编程接口上仍然可以调用connect()函数,用来限制只与某地址、端口通信。在调用了connect()函数后,向该地址发送数据时不需要再指定IP和端口了
可以检查到数据是否发送失败
DatagramProtocol
- startProtocol():当Protocol实例被第一次作为参数传给listenUDP()时调用
- stopProtocol():当所有连接都关闭后被调用
- connectionRefused():当数据发送失败的时候被调用
# coding:utf8
import sys,threading,time
from datetime import datetime
from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor
class Echo(DatagramProtocol):
'''
ConnectedUDP
'''
def __init__(self,host:str,port:int):
'''
构造函数
:param host: 目标地址
:param port: 目标端口
'''
self.host = host
self.port = port
def startProtocol(self):
'''
listenUDP()时调用
:return:
'''
self.transport.connect(self.host,self.port)
print('Connection Create !')
def connectionRefused(self):
'''
当数据发送失败的时候被调用
:return:
'''
print('sent failed !')
pass
def stopProtocol(self):
'''
当所有连接都关闭后被调用
:return:
'''
print('Connection close !')
pass
def datagramReceived(self, datagram: bytes, addr):
'''
接收数据事件
:param datagram:
:param addr:
:return:
'''
print('Got data from :%s' % (addr,))
print(datagram.decode('utf8'))
host = '127.0.0.1'
port = 8010
protocol = Echo(host,8009)
b_stop = False
def routine():
while not b_stop:
time.sleep(5)
str_msg = 'hello , i am %s %s' % (sys.argv[0], datetime.now())
protocol.transport.write(str_msg.encode('utf8'))
threading.Thread(target=routine).start()
reactor.listenUDP(port,protocol)
reactor.run()
b_stop=True