Я уверен, что не существует такого понятия, как «правильный» путь.
Если вы не хотите, не должны или не можете использовать любую из существующих реализаций сервера, общая идея (в псевдокоде):
ss = serversocket()
ss.bind ()
while (True):
cs = ss.accept ()
spawnCommThread (cs)
В CommThread для каждого клиента вы позаботитесь о том, чтобы прочитать данные из сокета, возвращенного методом accept, связаться с вашим клиентом и умереть, когда клиент закрывает соединение или задан другой критерий.