Most server implementations would fork (or pre-fork) and hand off the work to another process, which can close the socket after it finishes sending. The main process that is handing the accept() connections is never closed. So you never get into a TIMEWAIT state.
However, during development and testing you often crash and get into a TIMEWAIT state, that can take between 30s and 120s to expire. So in this case you want to use SO_REUSEADDR on the socket options. And in general your server should use SO_REUSEADDR.
However, SO_REUSEADDR does not let you start a second server on the same port if the port is already in use. This is why most TCP servers use a worker model, where only one master process opens the socket then it forks after each accepted connection (or pre-forks and hands out work to pre-forked and waiting workers).
Google introduced SO_REUSEPORT to enable them to create a simple server process model that can be executed multiple times on the same host, and each server process can open the same local port. To do so, they specify SO_REUSEPORT and then the open succeeds. Incoming connections are handed off fairly to each server listening on the same port, and this is done by the kernel. So this avoids the more complex (and sometimes unfair) user-land pre-forked or multi-threaded but single port server model.
SO_REUSEPORT was introduced in kernel 3.9 (but BSD had it before that).
With your simple server, SO_REUSEPORT would help you out, but you need to use kernel 3.9.
If you can't use kernel 3.9, then your server code needs to fork() after accept(), and in the parent: close the socket (from accept) and continue the loop to go back into accept() for more; (2) in the child, write to the socket (from accept) and close it and exit.
EDIT: in your case, for (2) return the socket descriptor to the caller. The parent loops back to accept more, and never returns from this function call.