gpt4 book ai didi

python - 使用 Twisted Python 的 UDP 客户端和服务器

转载 作者:太空狗 更新时间:2023-10-29 22:10:06 27 4
gpt4 key购买 nike

我想创建一个服务器和客户端,使用 Twisted 从网络发送和接收 UDP 数据包。我已经用 Python 中的套接字编写了这个,但想利用 Twisted 的回调和线程功能。但是,我在 Twisted 的设计方面需要帮助。

我想接收多种类型的数据包,但我们假设只有一种:

class Packet(object):
def __init__(self, data=None):
self.packet_type = 1
self.payload = ''
self.structure = '!H6s'
if data == None:
return

self.packet_type, self.payload = struct.unpack(self.structure, data)

def pack(self):
return struct.pack(self.structure, self.packet_type, self.payload)

def __str__(self):
return "Type: {0}\nPayload {1}\n\n".format(self.packet_type, self.payload)

我做了一个协议(protocol)类(几乎是示例的直接副本),当我从另一个程序发送数据时它似乎可以工作:

class MyProtocol(DatagramProtocol):
def datagramReceived(self, data, (host, port)):
p = Packet(data)
print p

reactor.listenUDP(3000, MyProtocol())
reactor.run()

我不知道的是如何创建一个可以在网络上发送任意数据包的客户端,这些数据包会被 react 器接收:

# Something like this:
s = Sender()
p = Packet()
p.packet_type = 3
s.send(p.pack())
p.packet_type = 99
s.send(p.pack())

我还需要确保在客户端和服务器上设置重用地址标志,以便我可以在同一设备上同时运行每个实例的多个实例(例如,一个脚本正在发送心跳,另一个脚本响应心跳等) ).

谁能告诉我如何用 Twisted 完成这件事?

更新:

这就是我在 Python 中使用套接字的方式。我可以同时运行多个监听器和发送器,它们都可以听到对方的声音。我如何使用 Twisted 获得此结果? (听力部分不需要是一个单独的过程。)

class Listener(Process):
def __init__(self, ip='127.0.0.1', port=3000):
Process.__init__(self)
self.ip = ip
self.port = port

def run(self):
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((self.ip, self.port))

data, from_ip = sock.recvfrom(4096)
p = Packet(data)
print p

class Sender(object):
def __init__(self, ip='127.255.255.255', port=3000):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.ip = (ip, port)

def send(self, data):
self.sock.sendto(data, self.ip)

if __name__ == "__main__":
l = Listener()
l.start()
s = Sender()
p = Packet()
p.packet_type = 4
p.payload = 'jake'
s.send(p.pack())

工作解决方案:

class MySender(DatagramProtocol):
def __init__(self, packet, host='127.255.255.255', port=3000):
self.packet = packet.pack()
self.host = host
self.port = port

def startProtocol(self):
self.transport.write(self.packet, (self.host, self.port))

if __name__ == "__main__":
packet = Packet()
packet.packet_type = 1
packet.payload = 'jake'

s = MySender(packet)

reactor.listenMulticast(3000, MyProtocol(), listenMultiple=True)
reactor.listenMulticast(3000, s, listenMultiple=True)
reactor.callLater(4, reactor.stop)
reactor.run()

最佳答案

就像上面的服务器示例一样,还有一个客户端示例。这应该可以帮助您入门:

好的,这是一个使用数据报协议(protocol)的简单心跳发送器和接收器。

from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor
from twisted.internet.task import LoopingCall
import sys, time

class HeartbeatSender(DatagramProtocol):
def __init__(self, name, host, port):
self.name = name
self.loopObj = None
self.host = host
self.port = port

def startProtocol(self):
# Called when transport is connected
# I am ready to send heart beats
self.loopObj = LoopingCall(self.sendHeartBeat)
self.loopObj.start(2, now=False)

def stopProtocol(self):
"Called after all transport is teared down"
pass

def datagramReceived(self, data, (host, port)):
print "received %r from %s:%d" % (data, host, port)


def sendHeartBeat(self):
self.transport.write(self.name, (self.host, self.port))



class HeartbeatReciever(DatagramProtocol):
def __init__(self):
pass

def startProtocol(self):
"Called when transport is connected"
pass

def stopProtocol(self):
"Called after all transport is teared down"


def datagramReceived(self, data, (host, port)):
now = time.localtime(time.time())
timeStr = str(time.strftime("%y/%m/%d %H:%M:%S",now))
print "received %r from %s:%d at %s" % (data, host, port, timeStr)



heartBeatSenderObj = HeartbeatSender("sender", "127.0.0.1", 8005)

reactor.listenMulticast(8005, HeartbeatReciever(), listenMultiple=True)
reactor.listenMulticast(8005, heartBeatSenderObj, listenMultiple=True)
reactor.run()

广播的例子简单的修改了上面的方法:

from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor
from twisted.internet.task import LoopingCall
import sys, time

class HeartbeatSender(DatagramProtocol):
def __init__(self, name, host, port):
self.name = name
self.loopObj = None
self.host = host
self.port = port

def startProtocol(self):
# Called when transport is connected
# I am ready to send heart beats
self.transport.joinGroup('224.0.0.1')
self.loopObj = LoopingCall(self.sendHeartBeat)
self.loopObj.start(2, now=False)

def stopProtocol(self):
"Called after all transport is teared down"
pass

def datagramReceived(self, data, (host, port)):
print "received %r from %s:%d" % (data, host, port)


def sendHeartBeat(self):
self.transport.write(self.name, (self.host, self.port))



class HeartbeatReciever(DatagramProtocol):
def __init__(self, name):
self.name = name

def startProtocol(self):
"Called when transport is connected"
self.transport.joinGroup('224.0.0.1')
pass

def stopProtocol(self):
"Called after all transport is teared down"


def datagramReceived(self, data, (host, port)):
now = time.localtime(time.time())
timeStr = str(time.strftime("%y/%m/%d %H:%M:%S",now))
print "%s received %r from %s:%d at %s" % (self.name, data, host, port, timeStr)



heartBeatSenderObj = HeartbeatSender("sender", "224.0.0.1", 8005)

reactor.listenMulticast(8005, HeartbeatReciever("listner1"), listenMultiple=True)
reactor.listenMulticast(8005, HeartbeatReciever("listner2"), listenMultiple=True)
reactor.listenMulticast(8005, heartBeatSenderObj, listenMultiple=True)
reactor.run()

关于python - 使用 Twisted Python 的 UDP 客户端和服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3632210/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com