A socket is basically a way for a server program to communicate with many clients. Sockets can have several underlying protocols : TCP/IP sockets enable communication on the network, Unix sockets enable communication on a local machine.
Once a connection is established between the server and the client, both process get a new file descriptor where they can write to send a message to the other process and read for messages sent by the other process. On a local machine, this is mostly like having two pipes, one going in each way, and sharing the same file descriptor number.
The server socket is the part that accepts new connections. It is also a file descriptor in the server's process, but does not handle usual read/write requests. Instead it handles an "accept" syscall that basically waits for a new connection and when one arrives establishes the connection and returns the file descriptor number for that connection. The clients that wish to establish connections must issue a connect call on the server socket, which is identified either by a file name (for unix sockets) or by a network address.
There are several solutions for server software to handle communication with multiple peers at once. A first solution is to use multiple threads. Another solution available on most unix implementations is to use the select system call.