Overview
The client is the sending component of the Minitalk communication system. It converts a string message into individual bits and transmits each bit to the server using UNIX signals (SIGUSR1 for 0, SIGUSR2 for 1).
Source Code Location
client.c - Lines 1-93
Architecture
The client follows a straightforward transmission pipeline:- Validates command-line arguments (PID and message)
- Converts PID string to integer using
ft_atoi - Sends the message character-by-character via
send_message - Each character is transmitted as 8 individual signals
- Returns status code based on success or failure
PID Parsing Function
ft_atoi()
The string to convert to an integer. Expected to be a valid PID in string format.
The parsed integer value, with sign applied if present.
Parsing Algorithm
Skip Whitespace
- Space (
) = ASCII 32 - Tab (
\t) = ASCII 9 - Newline (
\n) = ASCII 10 - Vertical tab (
\v) = ASCII 11 - Form feed (
\f) = ASCII 12 - Carriage return (
\r) = ASCII 13
Convert Digits
- Multiplies current number by 10 (shift decimal place)
- Adds the digit value (ASCII ‘0’ = 48, so
'5' - '0' = 5)
Example Conversion
Converting a string to integer
Converting a string to integer
| Step | Character | i | sign | num | Action |
|---|---|---|---|---|---|
| 1 | | 0 | 1 | 0 | Skip whitespace |
| 2 | | 1 | 1 | 0 | Skip whitespace |
| 3 | - | 2 | -1 | 0 | Set sign to -1 |
| 4 | 1 | 3 | -1 | 1 | num = (0 * 10) + 1 |
| 5 | 2 | 4 | -1 | 12 | num = (1 * 10) + 2 |
| 6 | 3 | 5 | -1 | 123 | num = (12 * 10) + 3 |
| 7 | 4 | 6 | -1 | 1234 | num = (123 * 10) + 4 |
| 8 | \0 | 7 | -1 | 1234 | Stop and return |
-1 * 1234 = -1234Message Transmission Function
send_message()
The Process ID of the server to send signals to. Must be a valid running process ID.
The message string to transmit. Each character will be sent as 8 bits (most significant bit first).
0on successful transmission1if anykill()call fails
Bit Extraction Logic
Understanding Bit Extraction: (str[i] >> bits) & 1
Understanding Bit Extraction: (str[i] >> bits) & 1
This expression extracts individual bits from a character, starting from the most significant bit (MSB).Example: Sending ‘A’ (ASCII 65 =
The bits are sent MSB-first (left to right):
Breakdown:
Right Shift Operation:str[i] >> bits- Shifts all bits in the character to the right by
bitspositions - Higher-order bits are filled with 0
- Lower-order bits are discarded
... & 1- Masks all bits except the least significant bit (LSB)
- Result is either 0 or 1
Example: Sending ‘A’ (ASCII 65 = 0b01000001)
| Iteration | bits | c >> bits | Binary Result | & 1 | Signal Sent |
|---|---|---|---|---|---|
| 1 | 7 | 65 >> 7 | 0b00000000 | 0 | SIGUSR1 |
| 2 | 6 | 65 >> 6 | 0b00000001 | 1 | SIGUSR2 |
| 3 | 5 | 65 >> 5 | 0b00000010 | 0 | SIGUSR1 |
| 4 | 4 | 65 >> 4 | 0b00000100 | 0 | SIGUSR1 |
| 5 | 3 | 65 >> 3 | 0b00001000 | 0 | SIGUSR1 |
| 6 | 2 | 65 >> 2 | 0b00010000 | 0 | SIGUSR1 |
| 7 | 1 | 65 >> 1 | 0b00100000 | 0 | SIGUSR1 |
| 8 | 0 | 65 >> 0 | 0b01000001 | 1 | SIGUSR2 |
0, 1, 0, 0, 0, 0, 0, 1Signal Transmission
Bit = 1
Sends
SIGUSR2 to represent binary 1Bit = 0
Sends
SIGUSR1 to represent binary 0kill() System Call
Sends a signal to a process or group of processes.Parameters:
pid: Target process IDsig: Signal number (SIGUSR1orSIGUSR2)
0on success-1on error (setserrno)
Timing Delay
700 microseconds delay between each signal transmission. This prevents signal queue overflow and ensures the server has time to process each bit before the next arrives.
Suspends execution for
usec microseconds. 700µs = 0.7 milliseconds.Main Function
main()
Argument count. Must be exactly 3 (program name, PID, message).
Argument vector:
argv[0]: Program name (”./client”)argv[1]: Server PID as stringargv[2]: Message to send
0on successful message transmission1on any validation or transmission error
Validation and Execution Flow
Argument Count Validation
- Exactly 3 arguments provided
- The message string (
argv[2]) is not NULL
PID Format Validation
Message Transmission
send_message() with:- Converted PID from
ft_atoi(argv[1]) - Message string cast to
unsigned char*
send_message() returns non-zero (failure), displays error and exits.Error Handling Summary
Invalid Arguments
Exit Code: 1
Message: “Usage : ./client <PID> <string to send>”
Message: “Usage : ./client <PID> <string to send>”
Non-Numeric PID
Exit Code: 1
Message: “Wrong PID”
Message: “Wrong PID”
Signal Send Failure
Exit Code: 1
Message: “Client failed sending signal”
Message: “Client failed sending signal”
Success
Exit Code: 0
Message: (none)
Message: (none)
Dependencies
Included Headers
ft_printf.h
Custom printf for error messages and output
signal.h
Signal constants and
kill() functiontime.h
Time-related functions (for
usleep() timing)System Calls Used
Sends signals to the server process. Core mechanism for bit transmission.
Introduces timing delays between signal transmissions to prevent queue overflow.
Execution Flow Diagram
Usage Examples
Performance Characteristics
Transmission Rate
Speed: Approximately 1,429 bits per second
- 700µs per bit
- 8 bits per character
- ~5.6ms per character
- ~178 characters per second
The 700µs delay is a balance between speed and reliability. Shorter delays risk signal loss; longer delays reduce throughput.
Key Design Decisions
Why MSB-First Transmission?
Why MSB-First Transmission?
The bits are sent from most significant to least significant (left to right). This matches:
- Human reading order
- Network byte order conventions
- Simpler reconstruction logic on the server side (always left-shift)
Why unsigned char* for the message?
Why unsigned char* for the message?
unsigned char* ensures:- Bit operations work correctly (no sign extension)
- All 8 bits are treated as data (0-255 range)
- Consistent behavior across all character values
Why validate PID format before sending?
Why validate PID format before sending?
ft_atoiparsing garbage values- Wasted signal transmission attempts
- Clearer error messages to the user