0

When i run my server, when server is listening, there is no way to stop the server rather than closing the terminal. I tried to handle ctrl+c using KeyboardInterrupt, but it doesnt work. I can terminate the script using ctrl+break but i dont know how to handle it in my code.

Here is the code for my server:

import socket


try:
    listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    listener.bind(('127.0.0.1', 4444))
    listener.listen(0)
    print('Listening...')
    listener.accept()
    print('Got a connection.')
except KeyboardInterrupt:
    print('Exiting...')
    exit()

How can i handle ctrl+break in my code?

Sahar
  • 89
  • 9
  • 1
    you need to catch the signal and handle that with some function `signal.signal(signal.SIGTERM, sigterm_handler)` – Alex Dec 08 '22 at 12:15
  • @Alex Can you please provide the code, i cant figure it out :( – Sahar Dec 08 '22 at 12:20
  • It reacts to ctrl-C as expected on Linux; this looks like a problem specific to Windows: https://stackoverflow.com/questions/15189888/python-socket-accept-in-the-main-thread-prevents-quitting – VPfB Dec 08 '22 at 12:35
  • @VPfB Yes it is specific to Windows. I tried to use a signal for at least catching the ctrl+break interrupt but i couldn't solve the problem. – Sahar Dec 08 '22 at 12:46
  • https://stackoverflow.com/a/5308168/3962537 | Or set a relatively short timeout (a second or something like that) for the accept, running it in a loop. – Dan Mašek Dec 08 '22 at 13:29

2 Answers2

0

something like this .

def handler(signum, frame):
    print 'Shutting down...'
    sys.exit(1)


signal.signal(signal.SIGTERM, handler)

while True:
    clientsocket, address = listener.accept()
    clientsocket.send(bytes("hi.","utf-8"))
Alex
  • 5,759
  • 1
  • 32
  • 47
0

If no client is waiting, socket.accept() hangs until a connection is made and can't be interrupted by CTRL-C or CTRL-BREAK. Use select.select() to wait for a connection to be readable from the server socket along with a timeout. The timeout will allow CTRL-C and CTRL-BREAK to be recognized.

CTRL-C raises KeyboardInterrupt, but CTRL-BREAK needs a signal handler. I've set up a custom exception to be raised on the SIGBREAK signal below:

import signal
import socket
import select

# Custom exception with same base class as KeyboardInterrupt
class CtrlBreakInterrupt(BaseException):
    pass

def handler(*args):
    raise CtrlBreakInterrupt

signal.signal(signal.SIGBREAK, handler)

# Set up server
with socket.socket() as sock:
    sock.bind(('', 5000))
    sock.listen()

    # Loop, accepting one connection at a time.
    while True:
        try:
            # Check server has a connection with timeout
            readable, _, _ = select.select([sock], [], [], 1.0)

            if sock in readable:
                with sock.accept() as (client, address):
                    while True:
                        data = client.recv(4096)
                        if not data: break
                        print(data)
        except CtrlBreakInterrupt:
            print('CTRL-BREAK')
            break
        except KeyboardInterrupt:
            print('CTRL-C')
            break
Mark Tolonen
  • 166,664
  • 26
  • 169
  • 251