我有一台在IP地址的端口3000上输出字符串的设备。我正在尝试构建一个将使用该字符串的脚本,对其进行修改,以便其他设备可以正确读取它,然后将其输出到其他设备正在侦听的端口。
我尝试过两种方式:线性地将输出设备和侦听设备都放在同一端口上;以及并行地,我使用threading
来尝试建立两个开放式telnet连接,一个在输出设备的端口上,另一个在侦听端口上。从技术上讲,任何一种都可以接受,但是我绝对希望并行解决方案能够正常工作,因为当字符串被接受或拒绝时,侦听设备会以输出作为响应,而我不想对此进行检查。并行解决方案使用的是生产者/消费者模型,其中生产者线程将输出设备检索到的字符串添加到队列中,而消费者线程将从队列中弹出字符串,进行适当的修改,然后将其输出到监听设备在另一个端口上。
并行解决方案:
import threading, telnetlib, hbconfig, time #hbconfig is a python file containing variables that are to be used by my code
try:
import Queue
except:
import queue as Queue
q = Queue.Queue(16)
class Listener:
def __init__(self):
time.sleep(1)
def run(self, lock):
try:
ltn = telnetlib.Telnet(hbconfig.IN_SERVER_ADDRESS, hbconfig.IN_PORT)
global q
while(True):
curr_string = ltn.read_until(b'\n')
curr_string.decode('utf-8')
try:
lock.acquire()
q.put(curr_string)
print("Listener put {0} in Queue".format(curr_string))
print("Queue: {0}".format(q))
lock.release()
pass
except:
print("Listener: Something went wrong...")
pass
time.sleep(.5)
except socket.timeout:
pass
class Speaker:
def __init__(self):
time.sleep(1)
def run(self, lock):
try:
stn = telnetlib.Telnet(hbconfig.OUT_SERVER_ADDRESS, hbconfig.OUT_PORT)
global q
while(True):
if not q.empty():
try:
lock.acquire()
curr_string = q.get()
new_string = fixString(curr_string)
stn.write(new_string.encode('ascii') + b'\n')
print("Speaker writing {0} to stn".format(new_string))
lock.release()
except:
print("Speaker: Something went wrong...")
lock.release()
pass
time.sleep(0.5)
except socket.timeout:
pass
def fixString():
#Modify the string as needed
def main():
try:
lock = threading.Lock()
q = Queue.Queue(16)
l = Listener()
s = Speaker()
lt = threading.Thread(target=(l.run), args=(lock,))
st = threading.Thread(target=(s.run), args=(lock,))
lt.daemon = True
st.daemon = True
lt.start()
st.start()
while True:
time.sleep(0.1)
except KeyboardInterrupt:
print("KeyboardInterrupt detected. Closing threads and ending program.")
if __name__ == '__main__':
main()
线性解决方案:
import telnetlib, hbconfig, time
def main():
try:
tn = telnetlib.Telnet(hbconfig.IN_SERVER_ADDRESS, hbconfig.IN_PORT)
while True:
curr_string = tn.read_until(b'\n')
curr_string.decode('utf-8')
new_string = fixString(curr_string)
try:
tn.write(new_string.encode('ascii') + b'\n')
print('Speaker wrote {0} to tn.'.format(new_string))
except socket.timeout: #Ignore socket timeouts
pass
except:
print('Speaker was unable to write {0} to tn.'.format(new_string))
pass
except KeyboardInterrupt: #Safely close telnet connection on KeyboardInterrupt
print("KeyboardInterrupt detected. Closing telnet connection and ending execution...")
tn.close()
print("Close successful. Goodbye!")
except Exception as e:
print(e)
if __name__ == "__main__":
main()
在并行解决方案中,最初我没有使用锁。在该迭代中,Listener
线程检索了第一个设备输出的字符串,并将其放入队列中。但是,应该将Speaker
线程弹出队列中的字符串,对其执行fixString
函数,然后将其输出到OUT_PORT
。但是,Speaker
似乎没有做任何事情。它从不打印任何成功声明,也不打印任何错误。 Listener
会按预期运行,但是Speaker
不会做任何事情。
添加锁后,我将收到一条错误消息,内容如下:
self._target(*self._args, **self._kwargs)
TypeError: run() argument after * must be an utterable, not _thread.lock
我知道这是在说kwarg必须是可迭代的,而不是锁,但是我不确定如何解决这个问题,也不确定如何解决原始解决方案(相同的方法,减去锁)。 / p>
在线性解决方案中,我会收到一条消息,说:
telnet connection closed.
,该程序将立即结束。我不确定为什么会这样。
任何人和所有帮助都将不胜感激,因为我从事这些工作已有一段时间了!预先谢谢你!