block
non block
msgflg: Controls the behavior of msgrcv():
0: The call will block until a message is
available.
IPC_NOWAIT: The call will return
immediately, with an error if no message is
available.
MSG_NOERROR: If the message is larger
than msgsz, it will be truncated.
Shared Memory
Shared memory allows two or more processes to share a given region of memory. This is
the fastest form of IPC, because the data does not need to be copied between the client and
the server. The only trick in using shared memory is synchronizing access to a given region
among multiple processes. If the server is placing data into a shared memory region, the
client shouldn't try to access the data until the server is done. Often, semaphores are used
to synchronize shared memory access.
The kernel maintains a structure with at least the following members for each shared
memory segment:
struct shmid_ds {
struct ipc_perm shm_perm; /* see Section 15.6.2 */
size_t shm_segsz; /* size of segment in bytes */
pid_t shm_lpid; /* pid of last shmop() */
pid_t shm_cpid; /* pid of creator */
shmatt_t shm_nattch; /* number of current attaches */
time_t shm_atime; /* last-attach time */
time_t shm_dtime; /* last-detach time */
time_t shm_ctime; /* last-change time */
.
.
.
};
The first function called is usually shmget, to obtain a shared memory identifier.
we described the rules for converting the key into an identifier and whether a new segment
is created or an existing segment is referenced. When a new segment is created, the
following members of the shmid_ds structure are initialized.
The ipc_perm structure is initialized as described in Section 15.6.2. The mode
member of this structure is set to the corresponding permission bits of flag. These
permissions are specified with the values from Figure 15.24.
shm_lpid, shm_nattach, shm_atime, and shm_dtime are all set to 0.
shm_ctime is set to the current time.
shm_segsz is set to the size requested
The shmctl function is the catchall for various shared memory operations.
Once a shared memory segment has been created, a process attaches it to its address
space by calling shmat.
When we're done with a shared memory segment, we call shmdt to detach
The addr argument is the value that was returned by a previous call to shmat. If successful,
shmdt will decrement the shm_nattch counter in the associated shmid_ds structure.
STREAM-Based Pipes
A stream based pipe is a bidirectional(full-duplex) pipe.
To obtain bidirectional data flow between a parent and a child only a single stream
can be used.
SOCKETS
Sockets
bind
listen
connect
accept
send
sendto
recv
recvfrom
shutdown
A Stream socket Example
Client/Server Message-Handling Example
What Are Sockets?
• Sockets provide a way for processes to communicate, either on the same
machine or over a network.
• In Unix programming, sockets are used for Inter-Process Communication
(IPC) and network programming.
There are two main types of sockets in Unix:
• Stream Sockets (SOCK_STREAM) – used for TCP communication.
• Datagram Sockets (SOK_DGRAM) – used for UDP communication.
End of Module 5
TCP Server Example (C)
// tcp_server.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#define PORT 8080
#define BUFFER_SIZE 1024
int main() {
int server_fd, new_socket;
struct sockaddr_in address;
char buffer[BUFFER_SIZE] = {0};
char *response = "Hello from server!";
int addrlen = sizeof(address);
// Create socket
server_fd = socket(AF_INET, SOCK_STREAM, 0);
// Bind
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);
bind(server_fd, (struct sockaddr *)&address, sizeof(address));
// Listen
listen(server_fd, 3);
printf("Server waiting for connection...\n");
// Accept
new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen);
read(new_socket, buffer, BUFFER_SIZE);
printf("Client says: %s\n", buffer);
// Respond
send(new_socket, response, strlen(response), 0);
printf("Response sent to client.\n");
close(new_socket);
close(server_fd);
return 0;
}
TCP Client Example (C)
// tcp_client.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#define PORT 8080
#define BUFFER_SIZE 1024
int main() {
int sock;
struct sockaddr_in serv_addr;
char *message = "Hello from client!";
char buffer[BUFFER_SIZE] = {0};
// Create socket
sock = socket(AF_INET, SOCK_STREAM, 0);
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr);
// Connect
connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
// Send
send(sock, message, strlen(message), 0);
// Receive
read(sock, buffer, BUFFER_SIZE);
printf("Server says: %s\n", buffer);
// Close
close(sock);
return 0;
Compile & Run
gcc tcp_server.c -o server
gcc tcp_client.c -o client
./server # In one terminal
./client # In another terminal