- Follow CLEAN CODE principles:
- Prefer clear naming over comments that explain trivial code.
- Keep functions short and focused on one responsibility.
- Avoid duplicated logic; extract shared behavior.
- Use explicit error handling and readable control flow.
- Keep formatting consistent and predictable.
- Follow SOLID principles where applicable:
- Single Responsibility: one reason to change per function/module.
- Open/Closed: extend behavior by composition/extraction rather than editing unrelated logic.
- Liskov Substitution: keep contracts predictable when refactoring APIs.
- Interface Segregation: expose small focused interfaces/helpers.
- Dependency Inversion: depend on abstractions and injectable collaborators when practical.
- Keep examples educational: readability and explainability have priority over micro-optimizations.
- Preserve behavior unless the user asks for functional changes.
- Prefer
statichelper functions for local modularity. - Validate all external input (CLI args, parsed numbers, socket results).
- Handle resource cleanup explicitly (
free,close,freeaddrinfo) on all error paths. - Use compiler warnings as quality gates (
-Wall -Wextra -Wpedantic) and keep builds warning-free. - Add comments where useful for oral explanation:
- protocol flow,
- network/socket decisions,
- non-obvious edge cases,
- cleanup and termination behavior.