System V Message Queues File Server–Client Application — Overview & Architecture

 

System V Message Queues
File Server–Client Application — Overview & Architecture
Chapter 46 · TLPI · EmbeddedPathashala
Part
1 of 4
Topic
Architecture
Level
Intermediate
Series
Linux IPC

What This Tutorial Covers

This part explains what the SysV Message Queue File Server–Client application does, why it is designed the way it is, what message types are used, and how the overall communication flow looks. No code details yet — just the big picture you need before reading the code.

The application lets a client send the name of a file to a server. The server reads that file and sends the contents back — all through System V message queues. It is a classic IPC example that shows real-world patterns used in embedded Linux and server software.

Key Terms in This Tutorial

System V MQ msgget() msgsnd() msgrcv() IPC_PRIVATE SERVER_KEY RESP_MT_DATA RESP_MT_FAILURE RESP_MT_END Concurrent Server fork() SIGCHLD atexit()

What is a System V Message Queue?

A System V message queue is a kernel-maintained linked list of messages. Each message has a type (a positive long integer) and a data body. Processes can send and receive messages independently — unlike pipes which are strictly one-way byte streams.

Key advantages over pipes for this file-server scenario:

  • Message boundaries are preserved — each send/receive is one complete message, not a byte stream.
  • Multiple clients can write to one server queue using different message types.
  • Selective receive — a process can pick messages of a specific type, ignoring others.
  • Bidirectional — the server replies directly to each client’s private queue.
Note: System V IPC objects (message queues, semaphores, shared memory) persist in the kernel until explicitly deleted with msgctl(id, IPC_RMID, NULL) or system reboot. This is different from pipes which disappear when all file descriptors are closed.

Application Overview — What the Program Does

The application has two programs: a server and a client.

Role What It Does Queue Used
Server Waits for file requests from any client. Opens the requested file and sends its contents back in chunks. One well-known server queue (fixed key)
Client Sends a file pathname to the server. Receives file contents and prints them. Its own private queue (IPC_PRIVATE key)

The server runs continuously and handles multiple clients at the same time by forking a child process for each request.

Architecture Diagram — Communication Flow

Below is a visual showing how server, clients, and message queues relate to each other:

CLIENT 1
Private Queue A
IPC_PRIVATE

① REQUEST (pathname)
② RESPONSE (file data)

SERVER
Server Queue
SERVER_KEY
Forks child per request

① REQUEST (pathname)
② RESPONSE (file data)

CLIENT 2
Private Queue B
IPC_PRIVATE

■ Client sends request to SERVER_KEY queue ■ Server child replies to client’s private queue ■ Each client has its own IPC_PRIVATE queue

The important design point: every client has its own reply queue. The client passes its queue ID inside the request message so the server knows where to send the reply.

Message Types Used in This Application

Both request and response messages use a long mtype field. This field controls which process receives the message when multiple messages are in a queue.

Request Message

Field Type Purpose
mtype long Any positive value (e.g. 1) — server reads all types
clientId int Queue ID of this client’s private reply queue
pathname char[] Path of the file the client wants

Response Message Types (Server → Client)

Constant Meaning Data field
RESP_MT_FAILURE Server could not open the file Error description string
RESP_MT_DATA A chunk of the file contents Up to RESP_MSG_SIZE bytes of file data
RESP_MT_END End of file — no more data Zero-length (empty)
Why three response types? The client needs to distinguish between “here is data”, “transfer is done”, and “an error happened” without any out-of-band signaling. Using different mtype values is the clean SysV MQ way to do this — no extra flag fields needed.

Step-by-Step Message Flow
Step Who What Happens
1 Server startup Creates server queue with well-known key SERVER_KEY. Starts waiting for requests.
2 Client startup Creates its own private queue with IPC_PRIVATE. Registers atexit() handler to delete this queue on exit.
3 Client → Server Client sends a request message to the server queue. The message contains the file pathname and the client’s queue ID.
4 Server Server receives the request and fork()s a child process to handle it. Parent loops back to wait for the next request.
5 Server child Tries to open the requested file. If it fails, sends RESP_MT_FAILURE to the client queue.
6 Server child If file opened OK, reads chunks and sends each as a RESP_MT_DATA message to client queue.
7 Server child After all data sent, sends one RESP_MT_END message (zero data) and exits.
8 Client Checks first response. If RESP_MT_FAILURE, prints error and exits. Otherwise loops receiving RESP_MT_DATA messages until it gets RESP_MT_END.

Why Does Each Client Use IPC_PRIVATE?

IPC_PRIVATE is a special key that tells the kernel: “create a brand new queue that nobody else knows about yet.” No other process can accidentally connect to it because it has no fixed key.

This solves a key problem: if two clients both tried to receive from a shared response queue, they might steal each other’s messages. With IPC_PRIVATE:

  • Each client gets a unique queue ID returned by msgget().
  • The client puts this ID in the request so the server knows exactly where to reply.
  • No other process knows this ID, so only this client gets the responses.
Cleanup: Since IPC_PRIVATE queues are not named, they must be explicitly deleted. The client registers a cleanup function with atexit() so the queue is removed even if the client exits abnormally.

Code Example — Message Structures

Before writing server or client code, you define the message structures that both sides share (usually in a header file):

/* svmsg_file.h — shared header for server and client */

#include <sys/msg.h>
#include <fcntl.h>

#define SERVER_KEY   0x1aaaaaa1   /* well-known key for server queue */
#define RESP_MSG_SIZE  8192        /* max bytes of file data per message */

/* Response message types */
#define RESP_MT_FAILURE  1   /* server could not open file */
#define RESP_MT_DATA     2   /* message contains file data  */
#define RESP_MT_END      3   /* end of file, no more data   */

/* Request message: client → server */
struct requestMsg {
    long  mtype;            /* message type (always 1) */
    int   clientId;         /* client's reply queue ID  */
    char  pathname[PATH_MAX]; /* file to serve           */
};
#define REQ_MSG_SIZE  (sizeof(struct requestMsg) - sizeof(long))

/* Response message: server → client */
struct responseMsg {
    long  mtype;                   /* RESP_MT_FAILURE/DATA/END */
    char  data[RESP_MSG_SIZE];     /* file data or error text  */
};

The size argument to msgsnd/msgrcv excludes the leading mtype field. That is why macros like REQ_MSG_SIZE subtract sizeof(long).

Summary of This Part
SysV MQ vs pipes Server queue with SERVER_KEY Client private queue with IPC_PRIVATE Three response message types 8-step communication flow Shared header file design

In the next part we go deeper into the concurrent server design — how forking works, how zombie processes are prevented, and how SIGCHLD is handled.

Quick Interview Questions — Architecture
  1. Why does a SysV message queue file server use IPC_PRIVATE for client reply queues?
  2. What are the three response message types used in this application and when is each sent?
  3. Why does the client embed its queue ID inside the request message?
  4. What is the difference between SERVER_KEY and IPC_PRIVATE?
  5. Why must the client delete its queue using atexit() instead of a normal close call?
  6. How does the server distinguish between multiple clients if all requests go to one queue?
  7. What problem would arise if all clients shared a single response queue?

Continue Learning

Next: Concurrent Server Design — fork(), SIGCHLD, zombie reaping

Next Part → Home

Leave a Reply

Your email address will not be published. Required fields are marked *