This is a Huge subject.
However, there are some things you can do to make it manageable.
The server has shared state. That means multiple readers and multiple writers. You have many, many choices for handling this.
A database. Most databases include locks to prevent concurrent writes.
Locking. You can use OS-level locking on the filesystem to allow concurrent writes.
Transaction serialization. You can queue update requests into some kind of transaction serializer. Often, the queuing devolves to locking a file, but some message queues don't involve file system locks.
Once you have a way to write shared state, you now need a way to handle multiple, concurrent client connections. You can use processes or threads or some combination of the two.
You often want to have authentication (who a user is). You often want to have authorization (what that user is allowed to do.) There are several ways to handle this. OS's do it. Databases do it. Or you can use an LDAP server to maintain this information.
You may want to have a "session" where a user connects, is authenticated, and remains connected until their session ends. TCP/IP can help you handle this.
One of the great things that's happened in the last few years is the evolution of a standardized architecture for multi-client applications. It's sometimes called The World Wide Web.
Often, it works like this.
You have a database. MySQL or something similar. This handles persistence, locking, multiple writers and multiple readers for you.
You have a web server. Apache HTTPD or something similar. This handles multiple concurrent client connections for you.
You have a web application framework. This can handle authentication, authorization and session management for you, saving you from having to write all that.
You write your application as web-based transactions using the web framework and the various servers.