Oto rozwiązanie przy użyciu circuits Application Framework:
Kod:
#!/usr/bin/env python
from circuits.net.events import write
from circuits import handler, Component, Debugger
from circuits.net.sockets import TCPServer, UDPServer
class UDPTCPBroadcaster(Component):
def init(self):
self.clients = {}
self.tcp = TCPServer(("0.0.0.0", 7001), channel="tcp").register(self)
self.udp = UDPServer(("0.0.0.0", 7000), channel="udp").register(self)
def broadcast(self, data, exclude=None):
exclude = exclude or []
targets = (sock for sock in self.clients.keys() if sock not in exclude)
for target in targets:
self.fire(write(target, data), "tcp")
@handler("connect", channel="tcp")
def _on_tcp_connect(self, sock, host, port):
self.clients[sock] = {"host": sock, "port": port}
@handler("disconnect", channel="tcp")
def _on_tcp_disconnect(self, sock):
if sock not in self.clients:
return
del self.clients[sock]
@handler("read", channel="tcp")
def _on_tcp_read(self, sock, data):
data = data.strip().decode("utf-8")
print sock, data
@handler("read", channel="udp")
def _on_udp_read(self, peer, data):
# Broadcast to all connected TCP clients
self.broadcast(data)
app = UDPTCPBroadcaster()
Debugger().register(app)
app.run()
To robi dokładnie to, co jesteś po i oto wyniki testu ...
Terminal # 1 Running udptcpbroadcast.py
:
$ ./udptcpbroadcast.py
<registered[tcp] (<TCPServer/tcp 31492:MainThread (queued=0) [S]>, <UDPTCPBroadcaster/* 31492:MainThread (queued=4) [R]>)>
<registered[udp] (<UDPServer/udp 31492:MainThread (queued=0) [S]>, <UDPTCPBroadcaster/* 31492:MainThread (queued=5) [R]>)>
<registered[*] (<Debugger/* 31492:MainThread (queued=0) [S]>, <UDPTCPBroadcaster/* 31492:MainThread (queued=5) [R]>)>
<started[*] (<UDPTCPBroadcaster/* 31492:MainThread (queued=4) [R]>)>
<registered[select] (<Select/select 31492:MainThread (queued=0) [S]>, <TCPServer/tcp 31492:MainThread (queued=0) [S]>)>
<ready[tcp] (<TCPServer/tcp 31492:MainThread (queued=0) [S]>, ('0.0.0.0', 7001))>
<ready[udp] (<UDPServer/udp 31492:MainThread (queued=0) [S]>, ('0.0.0.0', 7000))>
<_read[udp] (<socket._socketobject object at 0x7f5645168c20>)>
<read[udp] (('10.0.0.2', 35718), '\x00')>
<_read[tcp] (<socket._socketobject object at 0x7f5645168bb0>)>
<connect[tcp] (<socket._socketobject object at 0x7f5645168c90>, '127.0.0.1', 57282)>
<_read[udp] (<socket._socketobject object at 0x7f5645168c20>)>
<read[udp] (('10.0.0.2', 35718), 'Hello\n')>
<write[tcp] (<socket._socketobject object at 0x7f5645168c90>, 'Hello\n')>
<_write[tcp] (<socket._socketobject object at 0x7f5645168c90>)>
^C<signal[*] (2, <frame object at 0x1c38120>)>
<stopped[*] (<UDPTCPBroadcaster/* 31492:MainThread (queued=0) [S]>)>
<close[udp] ()>
<close[tcp] ()>
<closed[udp] ()>
<disconnect[udp] (<socket._socketobject object at 0x7f5645168c20>)>
<disconnect[tcp] (<socket._socketobject object at 0x7f5645168bb0>)>
<disconnect[tcp] (<socket._socketobject object at 0x7f5645168c90>)>
<closed[tcp] ()>
Terminal nr 2 wysyłając komunikat UDP:
$ ./telnet.py -u localhost 7000
Trying localhost ...
Hello
^C
Terminal nr 3 otrzymaniu wiadomości transmisji UDP:
$ telnet localhost 7001
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Hello
Connection closed by foreign host.
Uwaga: To stronniczy odpowiedź/rozwiązanie. Jestem autorką obwodów :) Być może jeśli ktoś z Twisted Community może odpowiedzieć wersją skręconą dla porównania! - Należy również zauważyć, że narzędzie ./telnet.py
pochodzi bezpośrednio z circuits examples i jest klonem podobnym do telnetu z obsługą zarówno TCP, jak i UDP.
Aktualizacja: W przypadku, gdy nie chcesz „broadcast” do każdego podłączonego klienta na serwerze słuchania TCP można zmienić to zachowanie do ściśle określonych klientów podłączonych - Ale to zależy od Ciebie, jak to zrobić i zarządzaj nim. (którego klienta, w jaki sposób możemy na nie kierować itp.).
jest idea tutaj że przychodzące wiadomości na '' UDP/7000'' są kierowane do połączonych klientów na serwerze odsłuchu związany 'TCP/700''? –
Czy to ma znaczenie, gdy porty są różne? Tak, właśnie to próbuję zrobić. Miałem wrażenie, że zrobiło to przykładowe łącze "Bridging UDP to TCP". –
Jestem deweloperem [układy] (https://pypi.python.org/pypi/circuits) i tutaj jest to, co może * * praca: https://gist.github.com/prologic/ae987fe4f6fbbd9ca415 - I jeszcze tego nie testowałem :) –