General Structure of Network Applications
On the previous page, Working with Sockets, I covered the basic sockets functions and what each one does. Now on this page I describe the basic structure of network applications, demonstrate how those functions are used and how they work together, and link you to some sample applications that implement those basic network application structures. It is not enough to just know how to stuff the sockets API data structures and how to make the function calls; you also need to know how they are used in an actual application.
Most network applications are of the client/server type. A client/server application actually consists of two separate applications usually, but not always, running on different computers:
- the server, which provides a service
- the client, which contacts the server to request the service
There are a multitude of examples of client/server applications, including but not limited to:
- File and printer sharing -- allows the client to mount a directory on the server as if it were a drive physically attached to the client's machine
- telnet -- the client logs in to the server and conducts a command-line terminal session as if he were physically connected to the server. An encrypted form of this is called ssh ("secure shell").
- ftp -- the client logs in to the server and can upload and download files
- Network time services (time and ntp) which send the time when polled or that broadcast the time periodically
- Web servers and browsers
- Database servers -- the database is maintained on the server while the client sends commands (eg, in SQL) to update and query the database
- Chat rooms -- the server keeps track of who's logged in and relays messages between the clients
- Game servers and clients -- the server keeps track of the state of the game and of the players while the players send game commands and receive game status and other information
Even in non-client/server applications (eg, peer-to-peer), because of the way that a network connection needs to be established, most network connections still end up following the basic client/server pattern:
I am unable to think of even a single network application that does not follow this pattern in some way. OK, maybe a broadcast server, but even then the client/server roles are simply reversed with the broadcast client application running a server socket that binds to a specific pre-determined port and "listens" for the broadcast server application; the mechanics of working the connection are the same, just reversed from the overall roles of the applications. Even the new peer-to-peer (P2P) networks require the nodes to be "listening" on specific ports in order to establish a connection.
- One socket, the server, listens on a specific port waiting for another socket, the client, to send a message (udp) or try to connect (tcp).
- The client sends a message or tries to connect to the server on a pre-specified port.
Most networking applications involve one application waiting for a message from the other and then responding when it does receive a message. This situation presents itself very often and so needs to be studied and understood.Basically, the server uses a specific, pre-determined port to wait for a client to contact it, whereupon the service is performed, the client ends the session, and the server goes back to waiting for a client to contact it.
The idea of the predetermined port is that the client needs to know what port the server is listening on in order to contact the server. As covered in the discussion of ports, the client would know what port to contact the server on by one of various means:
- The server is using a "well-known" port (0 through 1023) that has been assigned to that service (eg, telnet(23), ftp(21), http(80), echo(7) -- see the
services
file on your computer; eg, at/etc/services
, atC:\WINDOWS\SYSTEM32\DRIVERS\ETC\SERVICES
).
- The server is using a registered port (1024 through 49151) for that particular application (eg, Kerberos kpop(1109) or eklogin(2105), Sun nfs(2049), ingreslock (1524) -- some are also listed in the
services
file)
- The server is using whatever arbitrary port and the client has been informed through other means which port that is; eg:
- By pre-arranged agreement.
- Via alternative communication (eg, email, phone call, word-of-mouth, newsgroup or forum posting)
- Via another server; ie, a service is set up for cataloguing servers and the client gets the server's address and port number from there, which means that the server had to have already notified the cataloguing server.
- The server itself gives the client a new port to connect to in order to open a second channel (eg, ftp(21) opens a second socket (20) for the actual transfer of data).
- The client discovered the server's open port through port-scanning. However, in this case the client is most likely not a legitimate user of the service.
- The TCPMUX service is running on port 1. The client connects to TCPMUX and requests the desired service by name, whereupon TCPMUX connects the client to that server.
Let's designate the two ends of the connection as the "listener" and the "sender." Basically, the listener socket binds to a specific port and waits to receive a message, either with the
listen()
function (tcp) or with arecvfrom()
(udp). The reason it has to bind to a specific port is because the sender must specify which remote port he is going to try to connect to, so the sender must know ahead of time which port that is going to be. This is why the well-known ports are used so much and why they are each reserved for a specific service. That way, your client can connect to the desired service on any server.On the other hand, the sender does not need to bind to a specific port. When he connects to the listener, the OS automatically binds his socket to an unused port. Then that port number is included in the header of the packets he sends, so the listener is automatically told what port to send the response to. Nice and neat.
The following tables outline the basic sequence of actions performed by both parties in client/server communication. These differ depending on whether it's a TCP or a UDP connection. And although it's also a UDP application, I include the broadcast client/server as a separate example because it essentially represents a complete reversal of the roles of client and server.The differences between the TCP and UDP protocols will come into play here, so you might want to review that topic at this point before continuing on.
Basically, in a client/server session using the TCP protocol, the client and server establish a connection over which they can pass several messages of virtually any size. The connection must be explicitly created (with the "Triple Handshake") and it must be explicitly shut down ("Shutting Down Gracefully"). By analogy, it's somewhat like a telephone conversation in which the connection is made, a series of messages are exchanged, and then the connection is closed.
Very basically, a TCP connection operates thus:
Here's what that sequence looks like in more detail:
- The server creates a special listening socket to listen for a client to try to connect.
- The client connects to the server using the "Triple Handshake".
- After the connection has been established, the server accepts the client.
- The client and server send and receive any number of messages of any size back and forth.
- Either the client or the server shuts down the connection (normally, it's the client).
Basic TCP Client/Server Sequence Server Client
1. Create a TCP socket with the socket()
function.2. Bind the socket to a specific port with the bind()
function.3.Call listen()
to have that socket listen for a client trying to connect to it.1. Create a TCP socket with the socket()
function.2. Connect to the server with the connect()
function.4. Accept the connection with the accept()
function, which creates a client socket and starts the actual session.3. Send ( send()
) the request.5. Receive ( recv()
) the client's request.6. Send ( send()
) a response.4. Receive ( recv()
) the server's response.7. Repeat the receive and send (Steps 5 & 6) as required. 5. Repeat the send and receive (Steps 3 & 4) as required. 6. Shut down ( shutdown(1)
) the connection.8. When the client's shutdown action is detected, finish sending any remaining data and shut down ( shutdown(1)
) the connection.7. When the server's shutdown action is detected, close the socket ( close()
orclosesocket()
) and exit.9. Close the client socket ( close()
orclosesocket()
).10. Continue Step 3. 8. Exit. TCP Server Example (under construction) TCP Client Example (under construction)
Basically, in a client/server session using the UDP protocol, the client and server send individual datagrams to each other, all of which are limited in size. By analogy, it's like sending a letter: you send a single message (called a "datagram") and hope that it arrives at its destination intact.
Very basically, a UDP "connection" operates thus:
Here's what that sequence looks like in more detail:
- The server creates a regular socket and waits until it receives a datagram from a client.
- The server sends a response to that client.
- The client may send the server another datagram, if he so chooses.
Basic UDP Client/Server Sequence Server Client
1. Create a UDP socket with the socket()
function.2. Bind the socket to a specific port with the bind()
function.3. Wait to receive ( recvfrom()
) a message from a client.1. Create a UDP socket with the socket()
function.2. Send ( sendto()
) the message to the server.4. Receive ( recvfrom()
) the client's message.5. Send ( sendto()
) a response, if required.3. Receive ( recvfrom()
) the server's response.6. Wait for the next message from a client (Step 3)
-- could be the same client or a different one.4. Repeat the send and receive as required.
(each of which will be seen by the server as a separate communication)5. Close the socket ( close()
orclosesocket()
).6. Exit. UDP Server Example (under construction) UDP Client Example (under construction)
A broadcast client/server application is a special kind of a UDP application. In this case, the roles are reversed in that it's now the client that waits to receive a message from the server. And instead of sending its datagram to only one host, the server uses a special broadcast address to send the datagram to every single host on the local network (routers are normally configured to block broadcasts, thus confining broadcasts to a single network segment).
There can also be applications where the broadcast server doesn't send an actual broadcast message, but instead works off of a kind of "subscriber list" of addresses to send the message to. In that case, the server would have to send the message not once but multiple times, once for every "subscriber". However, the server would also no longer be limited to just the local LAN segment, but could even send these messages out over the Internet. An example of this kind of a setup would be the list of trap addresses to be notified of events under Simple Network Management Protocol (SNMP).
Very basically, a broadcast client/server application operates thus:
- The client creates a regular socket and waits until it receives a datagram from the server.
- The server broadcasts a datagram to the entire local network.
- The client receives the datagram and processes it.
Here's what that sequence looks like in more detail:
Since the broadcast client/server is somewhat of a different beast than the previous two types, it may help to consider a few possible applications for you to see how it could be used. Remember that broadcasting is limited to a single LAN, since broadcast messages are normally blocked by routers.
Basic Broadcast Client/Server Sequence Server Client
1. Create a UDP socket with the socket()
function.2. Bind the socket to a specific port with the bind()
function.3. Wait for a broadcast message on that port. 1. Create a UDP socket with the socket()
function.2. Broadcast the message ( sendto()
).3. Close the socket ( close()
orclosesocket()
).4. Receive ( recvfrom()
) and process the broadcast message. Send (sendto()
) a response, if required.4. Periodically repeat Steps 1 through 3. 5. Go back to step 3. Broadcast Server Example (under construction) Broadcast Client Example (under construction)
- Time Service
- The time server periodically broadcasts its time and the clients use it to update their own time.
- A "Who Has This?" Service
- This is a simple discovery method. A user or program has requested a resource (eg, a particular file), so the server broadcasts a query asking everybody on the LAN who has that resource. The client that has that resource sends a datagram back to the server with enough information for the user/program to access that resource.
Note that the Address Recognition Protocol (ARP) is an example of this application. Ethernet knows nothing about IP addresses, but rather can only address a host by its hardware address, AKA its "Media Access Control Address" (MAC address). TCP/IP applications use IP addresses and know nothing about MAC addresses. So when a host addresses a peer on the LAN by its IP address, ARP broadcasts a message asking "Who has this IP address?". Every host on the LAN receives the message and examines the IP address, but only the host that has that IP address responds with its MAC address. The requesting host then uses that MAC address to send its packet over Ethernet -- plus it saves that MAC address in its ARP cache for reuse in the immediate future, thus avoiding having to use ARP too often.
- Request for a Service
- Here, the names have been reversed back to normal order, but the operation is still the same. A client needs a service but does not know the address of the server nor even whether a server is present. So the client broadcasts its request and waits for a server to fulfill the request.
A very common example of this is Dynamic Host Configuration Protocol (DHCP). A DHCP server has a pool of IP addresses that it dynamically leases out to hosts on the LAN. This pool of addresses normally only covers part of the range of addresses for that network segment; any devices, such as routers or printers, that require static addresses are assigned them outside the range of the dynamic address pools. A new host on a LAN starts out without an IP address, so it broadcasts a DHCP request, the DHCP server offers it an IP address, and the client accepts it. It is possible to have more than one DHCP server on a LAN (each managing different ranges of address) and so the client could receive more than one offer, but it will only accept one.
- Roll Call / Poll
- The server would broadcast a message requesting that all hosts on the LAN report back with certain information. That information could be host identification ("who's out there?"), host status/health, events/measurements recorded by the host, etc. As the hosts report back, the server would process the reports; eg, by logging the information in the network log, by detecting the loss of a host or addition of a new host (assuming the new host has this protocol running), by updating tables that match hosts with names, resources, or workloads, by detecting certain conditions that require it to respond by initiating certain processes.
In Windows networking, something like this would be done to handle NetBIOS, wherein one or more hosts would be set up as "Master Browser". Part of a host's startup is to broadcast its name and server type (32 flags identifying whether it's a workstation, server, SQL server, time source, NT server, Windows 95+, domain or backup controller, master or backup or potential browser, print queue server, Novell, Apple, Xenix, OSF, VMS, wfw, etc), whereupon the Master Browser adds it to its tables. Then periodically thereafter (eg, 12 or 30 minutes), the host would again broadcast that information and the Master Browser updates its tables accordingly. If the host does not send its update on schedule, then the Master Browser removes it from its tables. Or the client could send a request (eg, local list or domain enumeration) to which the Master Browser will respond with the requested information.
Another application comes to mind because of work I did in the late 1980's in the area of computerized greenhouse control. Since our application did not run TCP/IP nor Ethernet, the user had to manually add each sensor to the application database and then the application would periodically poll each sensor one at a time. If we had been able to set it up as a broadcast poll, then the application would have sent a single broadcast request for sensor readings and all of the sensors would respond (due to Ethernet collision detection and avoidance, only one would get through at a time, but eventually all would have gotten through).
Return to Top of Page
Return to DWise1's Sockets Programming Page
Return to DWise1's Programming Page
Share and enjoy!
First uploaded on 2007 January 06.
Updated 2011 July 18.