0

I have this python script:

#!/usr/bin/python3

import socket
from daemonize import Daemonize

class ListenOnPort:

    def __init__(self, port):
        self.port = port
        self.pid = f"./listen_on{port}.pid"
        print(f"init port {port}")

    def listen_on_port(self):
        HOST = ''                # Symbolic name meaning all available interfaces
        PORT = int(self.port)    # Arbitrary non-privileged port
        print(f"listen_on_({PORT})")
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
            s.bind((HOST, PORT))
            s.listen()
            conn, addr = s.accept()
            print(addr,conn)

def main(ports):
    for port in ports:
        print(f"doing port {port}")
        l = ListenOnPort(port=port)
        Daemonize(app=f"demon_{port}", pid=l.pid, action=l.listen_on_port).start()
        print("main() exiting.")

if __name__ == '__main__':
    main(ports=[50010,50020,50030])

I run it like this ...

$ python demon.py       

... and I get output like this:

doing port 50010
init port 50010

And it is listening on port 50010 and creates the pid file.

$ ls -l listen_on*pid
-rw-r--r--  1 redcricket  staff  5 Mar  9 20:41 listen_on50010.pid
$ nc -zv 127.0.0.1 50010
localhost [127.0.0.1] 50010 open

But what happened to ports 50020 & 50030? Why does my script only do port 50010?

Red Cricket
  • 9,762
  • 21
  • 81
  • 166
  • You need to set up the threads for each of the ports you want to listen to ([this answer may be what you are looking for](https://stackoverflow.com/questions/62027064/multiple-ports-within-one-function)), then you daemonize after that to detatch the program from the shell. – metatoaster Mar 10 '22 at 04:48
  • Alternatively, you may wish to have `socket.accept` to be [non-blocking](https://stackoverflow.com/questions/5308080/python-socket-accept-nonblocking). – metatoaster Mar 10 '22 at 04:55
  • @metatoaster all those answer are "blocking" I want my processes to run in the background. – Red Cricket Mar 10 '22 at 05:12
  • The way your code is currently set up is going to have sockets that block, the answers I linked fixes that problem for you. The point of daemonizing the process is to detatch it from its parent process (which is what you called "unblocking", even though it has nothing to do with blocking or unblocking when it's a matter of fork and detatch of a process), but it doesn't magically unblock things that block execution internally - `conn, addr = s.accept()` is currently blocking, so my linked answer addressed your specific issue here. – metatoaster Mar 10 '22 at 06:43
  • Your second problem: `Daemonize.start()` will in fact [exit the parent process](https://github.com/thesharp/daemonize/blob/master/daemonize.py#L103-L114) by default (that's one way to daemonize, which is to fork a child process, detatch it fully, and exit), so once that is called, even inside a for loop, it will fully exit the parent process (thus terminating the loop), leaving only the first `l.listen_on_port` running after being called at the end of the `start()` method. – metatoaster Mar 10 '22 at 07:05
  • I might want to use this https://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/ – Red Cricket Mar 12 '22 at 02:42
  • Fair, but that example code is basically the ancestor to the library you were using... – metatoaster Mar 12 '22 at 06:02

0 Answers0