Introduction
Weβll learn how to implement socket programming in C by building both server and client application. This is a beginner friendly tutorial that anybody can follow.
What Youβll Learn π
- How to set up sockets for communication.
- Handling errors effectively.
- Sending and receiving messages between a server and a client.
What is Socket Programming?
Socket programming enables communication between two applications over a network. In this tutorial, weβll create:
- A server that listens for client connections on a specific port.
- A client that connects to the server, sends a message, and receives a response.
Setting Up the Server
Here is the server.c program explained step by step:
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#define PORT 8080- Headers: Import necessary libraries for socket programming.
- PORT: Define the port number where the server will listen for client connections.
int server_fd, new_socket;
ssize_t valread;
struct sockaddr_in address;
int opt = 1;
socklen_t addrlen = sizeof(address);
char buffer[1024] = { 0 };
char* hello = "Hello from server";- Variables:
server_fd: File descriptor for the server's listening socket.new_socket: File descriptor for the client's connection.buffer: Used to store data received from the client.
Creating the Socket
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}- socket(): Creates a new socket using IPv4 (
AF_INET) and TCP (SOCK_STREAM). - Error Handling: Exit if the socket creation fails.
Configuring the Socket
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
perror("setsockopt");
exit(EXIT_FAILURE);
}- setsockopt(): Ensures the socket can reuse the port/address after restarting the program.
Binding the Socket
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);
if (bind(server_fd, (struct sockaddr*)&address, sizeof(address)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}- bind(): Associates the socket with the specified
PORTandaddress. htons(): Converts the port to network byte order.
Listening for Connections
if (listen(server_fd, 3) < 0) {
perror("listen");
exit(EXIT_FAILURE);
}- listen(): Puts the server into passive mode, waiting for incoming connections.
Accepting a Client Connection
if ((new_socket = accept(server_fd, (struct sockaddr*)&address, &addrlen)) < 0) {
perror("accept");
exit(EXIT_FAILURE);
}- accept(): Accepts a connection request from a client.
Handling Communication
valread = read(new_socket, buffer, 1024 - 1); // Read client message
printf("%s\n", buffer); // Print the client's message
send(new_socket, hello, strlen(hello), 0); // Send a response
printf("Hello message sent\n");Setting Up the Client
Hereβs the client.c program explained step by step:
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#define PORT 8080- Import libraries and define the port number.
Creating a Socket
if ((client_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("\n Socket creation error \n");
return -1;
}- Creates a TCP socket for the client.
Setting Up the Server Address
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) {
printf("\nInvalid address/ Address not supported \n");
return -1;
}inet_pton(): Converts the server's IP address to binary form.
Connecting to the Server
if ((status = connect(client_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr))) < 0) {
printf("\nConnection Failed \n");
return -1;
}- connect(): Establishes a connection to the server.
Sending and Receiving Data
send(client_fd, hello, strlen(hello), 0); // Send message to server
printf("Hello message sent\n");
valread = read(client_fd, buffer, 1024 - 1); // Read server's response
printf("%s\n", buffer);Running the Programs
- Compile:
gcc server.c -o server gcc client.c -o client - Run the Server:
./server - Run the Client:
./client
Output
- Server:
Hello from client Hello message sent - Client:
Hello message sent Hello from server
Refer to my GitHub Repository for the π Source Code
