Telnetlib问题:多线程和Telnet无法按预期运行

时间:2019-04-07 17:00:50

标签: python-3.x python-multithreading telnetlib

我有一台在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.,该程序将立即结束。我不确定为什么会这样。

任何人和所有帮助都将不胜感激,因为我从事这些工作已有一段时间了!预先谢谢你!

0 个答案:

没有答案