in reply to exit isn't killing children

Not a direct solution for your problem, but I noticed something that you might want to improve for a better style, and to show a clear understanding of socket programming.
  1. In the child process, $listener is not useful at all, so the child process should close it after being forked. Don't worry, this will not close the $listener in the parent process.
  2. Similarly, $client is not useful in the parent process, so the parent process should close each instance of $client, after it forked the child process for that particular $client. Again, don't worry, this will not close the $client in the child process.