3

I'm developing a small server system and I need to turn the server off whenever I type "exit()" into the console (the input is handled from another thread) I was wondering if there is a way to terminate the main thread while the socket is awaiting data. I've already tried using _thread.interrupt_main() with a keyboardInterrupt exception in a try block but it didn't work. I also tried os._exit() which worked but it doesn't clean up so I decided not to use it. My code:

import socket
import _thread
import os

clear = lambda: os.system("cls")

try:
    Server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    Server.bind(("localhost",port))
    Server.listen(2)
    clear()
    print("--------------------------------------")
    print("Server running on port %s" % str(port))
    print("--------------------------------------")
except Exception:
    print("error while starting server")
    input()
    exit()

def control():
    while True:
        command = input()
        if command == "exit()":
            #interrupt code here

_thread.start_new_thread(control,())

while True:
    con,ip = Server.accept()
    print(str(ip) + " Connected")

    try:
        cmd = str(con.recv(1024).decode())  #<-- interrupt this line
    except Exception:
        print("Error")
halfer
  • 19,824
  • 17
  • 99
  • 186
BlockCoder
  • 135
  • 2
  • 12

2 Answers2

3

sock.shutdown(socket.SHUT_RDWR) is quite handy if you have the socket in the main thread and the thread is blocked in recv/recvfrom/etc. The recv call will end up in an exception and you can use that to finish your thread if you need to.

debuti
  • 623
  • 2
  • 10
  • 20
1

Below code does what you want but on a basic level for closing connection of single client. You should restructure your code for handling multiple clients if you wish so. Best idea would be to start new thread for each connection of same socket connection so that you could handle them seperately.

import socket
import _thread
import os

clear = lambda: os.system("cls")
port = 1026
try:
    Server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    Server.bind(("127.0.0.1",1026))
    Server.listen(2)
    print("--------------------------------------")
    print("Server running on port %s" % str(port))
    print("--------------------------------------")
except Exception:
    print("error while starting server")
    input()
    exit()

def control(sock):
    while True:
        command = input()
        if command == "exit()":
            sock.close()
            os._exit(0)
            #interrupt code here


while True:
    con,ip = Server.accept()
    _thread.start_new_thread(control,(con,))
    print(str(ip) + " Connected")

    try:
        cmd = str(con.recv(1024).decode())  #<-- interrupt this line
    except Exception:
        print("Error")
mr_pool_404
  • 488
  • 5
  • 16
  • I know about os._exit() but I didn't want to use it because it doesn't call the cleanup handlers and doesn't flush stdio buffers. Is there any other way to do this? – BlockCoder Mar 03 '19 at 13:16
  • i have closed the sock connection before os._exit(). You will have to close all the handle before using it. As far as i know atleast regarding sockets you will have to manually take care of them. – mr_pool_404 Mar 03 '19 at 13:56
  • Check this link out.I think it would be useful. [https://stackoverflow.com/questions/323972/is-there-any-way-to-kill-a-thread] – mr_pool_404 Mar 03 '19 at 14:00
  • Thanks, I think I will stick to os._exit() for now since this is only for personal use. – BlockCoder Mar 03 '19 at 14:07