asyncio.run(main())
крутит рабочий цикл, пока переданная ей корутина не завершится. Если на момент завершения рабочего цикла какие-то корутины были в состоянии ожидания - упс, у них не будет шанса как-то отреагировать на произошедшее. Детали реализации я затрудняюсь пояснить - в частности, почему корутины всё-таки стартуют и успевают дойти до первого await вызова, и только потом умирают. Я где-то читал, что asyncio.sleep() вообще имеет отдельную очередь вызовов, возможно тут, какое-то взаимодействие.
Для линукса
netstat -nlp
покажет слушаемые порты, если установлен пакет net-tools.