smaxxx
smaxxx

Reputation: 139

Python Sockets - How to shut down the server?

I tried to make a simple chat system with the socket module in Python. everything works, except, that i need to kill the process everytime when i want to shutdown the server. And i don't want to do this everytime. So my question is:

How can i make a function, that when i type shutdown in the server terminal, it shutdowns the whole server?

I already tried to do this:

def close(self): server.close(self) server.shutdown(self)

But it doesn't work. When i type close(), nothing happens. Nothing.

Heres the full code of the server.py: https://pastebin.com/gA4QYmQe Every help is useful. Thanks.

Upvotes: 2

Views: 29998

Answers (2)

dileep chidurala
dileep chidurala

Reputation: 55

One other approach would be having a default admin-client that can control the server. Admin-client will be created when the server starts and from that client admin can shutdown and do any of the admin tasks on the server.

Upvotes: 0

Hannu
Hannu

Reputation: 12205

Well... there are many problems with the code (your "MY IP" and "SERVERIP" are probably not what you want, but this is beside the point.

Your close() function has a "self" parameter, which is pointless as this is not a class. You also need to move the close function to the beginning of your code if you want to call it from your try-except -structure. You need to call shutdown() first and then close(), and shutdown takes an argument. I modified your close() to do this and it works.

def close():
    server.shutdown(socket.SHUT_RDWR)
    server.close()
    print ("closed")

When you open your socket, you should also set SO_REUSEADDR to make the address reusable (meaning you can start the server again if you shut it down, instead of waiting for a minute for TIME_WAIT status to finish with your server port):

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

But how exactly are you calling close() when you type "shutdown" somewhere? You are not doing this. Your program is in the socket loop and is not reading keyboard input.

I see no point whatsoever adding keyboard input to this program. First, it adds complexity as you are operating with two possibly blocking inputs (socket input and keyboard input) and you would need to manage this. It is possible but definitely complicated. Second, it is faster to press Control + C instead of typing "shutdown" and hitting enter.

You currently do not call close after a keyboard interrupt. I added this to the inner KeyboardInterrupt (the outer you can remove - it is not doing anything and is never reached) and it now shuts down your program neatly, closing all connections. Remember to move close() function from the bottom of your code to the front before the try: statement:

    except KeyboardInterrupt:
        print("[!] Keyboard Interrupted!")
        close()
        break

If you want a remote shutdown (server shuts down if you type "shutdown" to the socket), you can add this to your server loop:

if message == "shutdown":
    close()
    exit(0)

There are other problems as well. For example, if you start your server, connect to it and shut down the connection, your server exits as it does not return to listen().

This is also (in my opinion), somewhat bad programming, as you use "server" as a global variable. I would rather create a class and put all socket operations in it, but if style is not important, this should work.

Hannu

Upvotes: 6

Related Questions