0

I wrote a udp no echo server in my program, I used thread to running and listen some message send by others. But it seems I couldn't stop it use tl.stop(), when I input q or quit. Some of my code is following:

            class treadListen(threading.Thread):
                def __init__(self):
                    self.running = True
                    threading.Thread.__init__(self)

                def run(self):
                    address = ('localhost', 16666)
                    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
                    sock.bind(address)
                    while True:
                        data = sock.recv(65535)
                        print "MESSAGE:{0}".format(data)
                    sock.close()

                def stop(self):
                    self.running = False
                # end of class thread_clock


            if __name__ == "__main__":
                tl = treadListen()
                tl.start()

                while True:
                    message = raw_input("CMD>")
                    if not message:
                        print "Please input command!"
                        continue
                    elif (message == 'quit') or (message == 'q'):
                        tl.stop()
                        break
                    else:
                        print "input is {0}".format(message)
                        # do something
                        continue
                print "[CONNECTION CLOSED!]"

I was trying to add sock.shutdown(socket.SHUT_RDWR) and sock.close() to def stop of class, but it doesn't work. How can I stop the thread safety? Thanks!

Archer Hu
  • 37
  • 11
  • Possible duplicate of [How do I capture SIGINT in Python?](http://stackoverflow.com/questions/1112343/how-do-i-capture-sigint-in-python) – rbp Jan 16 '16 at 17:09
  • you also misunderstand `elif`,`continue` and `break` – rbp Jan 16 '16 at 17:12

2 Answers2

1

Your while loop while True: works forever, so I guess your close or shutdown calls to the socket never can gets in way to work.

You should change while True: to while self.running: and that should do the trick.

st.
  • 579
  • 3
  • 11
  • I have try to use "while running:", but nothing change. – Archer Hu Jan 16 '16 at 17:15
  • `self` is also missing. Try: `while self.running:` in the thread. – ntki Jan 16 '16 at 17:16
  • @rbp has a break but it doesn't have any connection with treadListen class – st. Jan 16 '16 at 17:17
  • @ntki, use "while self.running:" nothing change, still in loop after input "q" – Archer Hu Jan 16 '16 at 17:21
  • I think whether it will not check the self.running until message coming that make nothing change? – Archer Hu Jan 16 '16 at 17:23
  • @ArcherHu Yes, it blocks on the `sock.recv()`. So you need to check the socket with a timeout. Either with a some mechanism like `select()` or setting timeout directly on the socket and handling the `socket.timeout` exception. – ntki Jan 16 '16 at 17:26
  • @rbp only if the thread is set to `daemon` mode, which is not the case here. – ntki Jan 16 '16 at 17:30
  • @ntki , it's helpful to know what happened. But when I add code "settimeout(1)", the program show error in 1 second because no message come. – Archer Hu Jan 16 '16 at 17:34
  • The problem solved, and I post an answer to show how to do that. Thank you guys, it's great to get your help! – Archer Hu Jan 16 '16 at 17:42
0

Thanks ntki,rbp,st. The problem solved use following code:

            class treadListen(threading.Thread):
                def __init__(self):
                    **self.running = True**
                    threading.Thread.__init__(self)

                def run(self):
                    address = ('localhost', 16666)
                    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
                    **sock.settimeout(1)**
                    sock.bind(address)
                    **while self.running:
                        try:
                            data = sock.recv(65535)
                            print "MESSAGE:{0}".format(data)
                        except Exception, e:
                            continue**
                    sock.close()

                def stop(self):
                    **self.running = False**
                # end of class thread_clock
Archer Hu
  • 37
  • 11