Skip to content

✉️Minitalk: communication between client and server with UNIX signals.

Notifications You must be signed in to change notification settings

freddyfleitas/minitalk_42

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

25 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Minitalk - @42Born2Code

Screenshot

Table of Contents

About the Project

Minitalk is a project from the second ring of the common core in the 42 cursus, focusing on sending messages from the client to the server using UNIX signals. This approach allows us to develop essential skills in signal handling and bitwise operations, crucial in software development.

Signals

A signal is a "notification" that one process can send to another process; UNIX signals are received and processed immediately. A common example is CTRL + C, which sends the SIGINT (INTERRUPT SIGNAL) to halt the process.

Types of Signals

Signal Name Number Purpose
SIGINT 2 Interruption (Ctrl-C)
SIGFPE 8 Floating-point error (e.g., division by zero)
SIGPIPE 13 Attempt to write to a broken connection
SIGALRM 14 Timer expiration
SIGUSR1 16 Customizable by the programmer
SIGUSR2 17 Customizable by the programmer

For Minitalk, we focus on SIGUSR1 and SIGUSR2 for interaction between programs.

Helpful resources

Used Functions

  1. signal(signalname, signalhandler):

    • This function is used to capture signals. It takes two parameters: the signal with which it will interact and the signal handler. The signal handler defines the action to be taken upon capturing the signal. The handler can be a user-created function or a specific action. In the case of a custom function, the prototype would be void handler(int signal), where signal is the number or name of the captured signal.
  2. kill(signalname, pid):

    • Allows us to send a signal to a specific process identified by its PID (Process Identifier). It takes two parameters: the signal we want to send and the PID of the target process.
  3. getpid():

    • Retrieves the subprocess number of the currently executing program.
  4. usleep(microseconds):

    • The usleep function instructs the program to pause for a specified duration (in microseconds) before processing the next signal. For a clearer understanding of the program's operation, especially during testing, the sleep function can be used instead. It performs the same function as usleep but operates in seconds, making it easier to observe how signals interact.

DISCLAIMER: It is recommended to interpret signals as quickly as possible since a delay in presenting a word can impact project performance.

Bitwise and ¿WHY IS IMPORTANT?

The term "bitwise" pertains to operations involving the manipulation of bits. In this context, working with data at the bit level proves advantageous, as the information transmitted through signals is compressed. This enables quicker and more efficient interpretation, ultimately contributing to the development of an optimized program that demands less storage space.

For a comprehensive understanding of bitwise operations, i recommend watching this informative video: Bitwise operators.

BitwiseTable

Building the thing.

Client.c

Sending Bits to the Server - sendbits Function

// Function to send bits to the server
void sendbits(int pid, char *str, int len)
{
    int i;
    int shift;

    i = 0;
    // Check if PID is valid
    if (pid == 0)
        return;

    // Check if the message is empty
    if (*str == 0)
    {
        printf("ERROR: Invalid message (empty)\n");
        return;
    }

    // Iterate through each character in the string
    while (i < len)
    {
        shift = 7;

        // Iterate through each bit of the character
        while (shift >= 0)
        {
            // Send signal based on the bit value
            if ((str[i] >> shift) & 1)
                kill(pid, SIGUSR1);
            else
                kill(pid, SIGUSR2);

            shift--;
            usleep(100); // Pause for signal processing
        }

        i++;
    }
}

Server.c

Signal Handler Function - signalhandler

void signalhandler(int signal)
{
    static int bit;               // Track the current bit position in the received byte
    static unsigned char letter;  // Store the reconstructed ASCII character
    int number;                   // Represent the bit value (0 or 1) based on the received signal

    if (signal == SIGUSR1)
        number = 1;
    else
        number = 0;

    letter = (letter << 1) + number;  // Update the ASCII character by shifting bits and adding the new bit
    bit++;

    // If a complete byte (8 bits) has been received
    if (bit == 8)
    {
        write(1, &letter, 1);  // Print the reconstructed ASCII character to the standard output
        letter = 0;            // Reset the letter variable for the next byte
        bit = 0;               // Reset the bit counter for the next set of signals
    }
}

Last recommendations and helpfull repositories

Improve your understanding of the Minitalk project by learning manual conversion between integer and binary. This key knowledge will allow you to better understand bitwise operations. Remember that shifting right is like dividing by 2, and shifting left is like powering by 2. These concepts are essential not only for Minitalk, but also for future projects that involve bit manipulation.

Special acknowledgment to those who aided in unraveling the complexities of Minitalk:

Their contributions have been instrumental in my understanding of Minitalk, and credit is duly given to them.

About

✉️Minitalk: communication between client and server with UNIX signals.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published