У меня есть устройство, которое выводит строки на порт 3000 моего IP-адреса.Я пытаюсь создать сценарий, который будет принимать эту строку, вносить в нее изменения, чтобы другое устройство могло ее правильно прочитать, а затем выводить ее на порт, который прослушивает мое другое устройство.
Iпытались сделать это двумя способами: линейно, в котором и устройство вывода, и прослушивающее устройство находятся на одном и том же порту, и Parallel, в котором я использую 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
Я знаю, что это говорит о том, что kwargs должен быть итеративным, а не блокировкой, но я не уверен, как исправить это, ни как исправить исходное решение (которое было таким же, за исключением блокировки).
В линейном решении я получаю сообщение, которое просто говорит: telnet connection closed.
, и программа просто сразу завершается.Я не уверен в том, почему это произошло.
Любая и вся помощь будет принята с благодарностью, так как я работал над этим некоторое время!Заранее спасибо!