networking – How do multiplayer servers handle receiving, handling, and sending packets?

I want to make a fighter jet simulator game.

The server (authoritative) and client communicate over udp.

The server sends out updates about the gamestate at a fixed rate. Think of plane positions, speeds, rotation, basically anything to do with physics.

On demand, the server sends out packets for spawning bullets and applying damage. So this is not at a fixed tickrate. This is done to sidestep the problem of superbullets and syncing fire rates with tick rates entirely. This class of packets also include chat messages.

How do I go about implementing this? I am using c/c++, programming raw sockets. I am running into the issue where the recvfrom function is blocking. I can set it to non-blocking using fnctl, yes, but that spams error messages because sometimes there are no packets waiting to be handled (I could handle it but egh, inelegant). Ideally I would like to prevent multithreading, but given that there seems to be no native event-driven or interrupt-driven way of receiving packets it seems I need to do that.

How do other game servers, like quake arena, set up their threads?

My idea:

  1. Main thread calculates game state, sends out packets at a fixed rate
  2. 1 child thread for listening for new packets (recvfrom loop)
  • If the incoming packet is a “i am shooting” packet, it performs checks, and broadcasts to every client that a bullet has spawned. It adds the bullet to the world, and the main thread will calculate the trajectory in the next or current tickcycle.
  • if the incoming packet is a chat message, perform checks and just broadcast it across clients.
  • if the incoming packet is any other kind of packet, put it in a queue for the main thread to handle (the queue is mutexxed)

Is this how I should make the child and main communicate?