Если у вас BSD, то, скорей всего, это не лечится, чтобы избежать проблем при повторном запуске демона/открытии порта используйте SO_REUSEADDR / SO_REUSEPORT. Если Linux, то это странно, потому что при нулевом лингере по идее должен идти RESET, а не закрытие сокета через FIN. Попробуйте устанавливать лингер при создании сокета. Возможно вы пропустили какие-то ситуации закрытия сокета, например когда закрытие соединения инициируется другой стороной.
+ если у вас протокол с долго живущими соединениями, которые могут подолгу простаивать без передачи данных, не забывайте использовать SO_KEEPALIVE, иначе клиенты за NAT'ом могут отваливаться втихую, что и приводит к многочисленным fin-wait'ам.
ChymeNik: про Windows не уверен как именно работает нулевой лингер, но точно могу сказать что коннекты в time-wait / fin-wait там ни к каким негативным последствиям, типа невозможности рестартануть сервис и слушать тот же порт, не приводят.