Python Twisted从TCP接收命令写入串口设备返回响应
我已经成功连接了USB调制解调器,并且客户端可以通过TCP连接到我的reactor.listenTCP。调制解调器接收到的数据会发送回客户端。我想把客户端发送过来的数据再发送给调制解调器,但我在实现这个功能时遇到了困难。任何帮助都将非常感谢!以下是我的代码:
from twisted.internet import win32eventreactor
win32eventreactor.install()
from twisted.internet import reactor
from twisted.internet.serialport import SerialPort
from twisted.internet.protocol import Protocol, Factory
from twisted.python import log
import sys
log.startLogging(sys.stdout)
client_list = []#TCP clients connecting to me
class USBClient(Protocol):
def connectionFailed(self):
print "Connection Failed:", self
reactor.stop()
def connectionMade(self):
print 'Connected to USB modem'
USBClient.sendLine(self, 'AT\r\n')
def dataReceived(self, data):
print "Data received", repr(data)
print "Data received! with %d bytes!" % len(data)
#check & perhaps modify response and return to client
for cli in client_list:
cli.notifyClient(data)
pass
def lineReceived(self, line):
print "Line received", repr(line)
def sendLine(self, cmd):
print cmd
self.transport.write(cmd + "\r\n")
def outReceived(self, data):
print "outReceived! with %d bytes!" % len(data)
self.data = self.data + data
class CommandRx(Protocol):
def connectionMade(self):
print 'Connection received from tcp..'
client_list.append(self)
def dataReceived(self, data):
print 'Command receive', repr(data)
#Build command, if ok, send to serial port
#????
def connectionLost(self, reason):
print 'Connection lost', reason
if self in client_list:
print "Removing " + str(self)
client_list.remove(self)
def notifyClient(self, data):
self.transport.write(data)
class CommandRxFactory(Factory):
protocol = CommandRx
def __init__(self):
client_list = []
if __name__ == '__main__':
reactor.listenTCP(8000, CommandRxFactory())
SerialPort(USBClient(), 'COM8', reactor, baudrate='19200')
reactor.run()
2 个回答
0
谢谢,我搞定了。之前无法让def notifyAll把数据发送到我的调制解调器……我这样做的:对每个客户端列表中的cli,cli.transport.write(data)
这是新代码:
import sys
from twisted.internet import reactor
from twisted.internet.protocol import Factory
from twisted.internet.protocol import Protocol
from twisted.internet.serialport import SerialPort
from twisted.python import log
log.startLogging(sys.stdout)
client_list = []#TCP clients connecting to me
usb_list = []
class USBClient(Protocol):
def __init__(self, network):
self.network = network
self.usb_list = []
def connectionFailed(self):
print "Connection Failed:", self
reactor.stop()
def connectionMade(self):
usb_list.append(self)
print 'Connected to USB modem'
USBClient.sendLine(self, 'AT\r\n')
def dataReceived(self, data):
print "Data received", repr(data)
print "Data received! with %d bytes!" % len(data)
for cli in client_list:
cli.transport.write(data)
#self.network.notifyAll(data)# !!AArgh..!Could not get this to work
pass
def lineReceived(self, line):
print "Line received", repr(line)
def sendLine(self, cmd):
print cmd
self.transport.write(cmd + "\r\n")
def outReceived(self, data):
print "outReceived! with %d bytes!" % len(data)
self.data = self.data + data
class CommandRx(Protocol):
def connectionMade(self):
print 'Connection received from tcp..'
client_list.append(self)
def dataReceived(self, data):
print 'Command receive', repr(data)
for usb in usb_list:
usb.transport.write(data)
def connectionLost(self, reason):
print 'Connection lost', reason
if self in client_list:
print "Removing " + str(self)
client_list.remove(self)
class CommandRxFactory(Factory):
protocol = CommandRx
def __init__(self):
self.client_list = []
def notifyAll(self, data):
for cli in self.client_list:
cli.transport.write('yipee')
if __name__ == '__main__':
tcpfactory = CommandRxFactory()
reactor.listenTCP(8000, tcpfactory)
SerialPort(USBClient(tcpfactory), '/dev/ttyUSB4', reactor, baudrate='19200')
reactor.run()
5
你的问题其实跟Twisted没关系,而是跟Python有关。可以看看这个常见问题的解答:
简单来说,如果你想在通过TCP连接的客户端发送数据,而你的协议是串行连接的,只需要把工厂的引用传给协议,这样你就可以用这个引用来建立连接。
下面是一些示例代码,大致展示了这个过程:
class USBClient(Protocol):
def __init__(self, network):
self.network = network
def dataReceived(self, data):
print "Data received", repr(data)
#check & perhaps modify response and return to client
self.network.notifyAll(data)
#...
class CommandRx(Protocol):
def connectionMade(self):
self.factory.client_list.append(self)
def connectionLost(self, reason):
if self in self.factory.client_list:
self.factory.client_list.remove(self)
class CommandRxFactory(Factory):
protocol = CommandRx
def __init__(self):
self.client_list = []
def notifyAll(self, data):
for cli in self.client_list:
cli.transport.write(data)
在初始化时,传入这个引用:
tcpfactory = CommandRxFactory()
reactor.listenTCP(8000, tcpfactory)
SerialPort(USBClient(tcpfactory), 'COM8', reactor, baudrate='19200')
reactor.run()