I’m writing a multiplayer server in C using sockets and pthreads. The project is separated by responsibility:
-- server.c/.h → networking (socket, bind, listen, accept, thread creation)
-- player.c/.h → player data structure and functions
-- game.c/.h → game logic
-- config.h → constants
When a new client connects, I need to:
Ask the client for a username
Validate it (check uniqueness)
Create a player object
Add it to the global player list
Then move the client into the lobby/menu loop
Right now this logic is inside a function like handle_client(...), which is called after accept().
Where should this function belong?
Inside server.c, meaning the server handles both networking and player initialization?
Inside player.c, even though that mixes networking I/O with data structure logic?
Or should I create a new module, e.g., controller.c, where the server only accepts sockets and the controller handles client interaction flow?
I want to maintain clean separation of responsibilities. Which design makes more sense?