what is socket programming?
Socket programming is a way of connecting two nodes on a network to communicate with each other.
One socket(node) listens on a particular port at an IP, while the other socket reaches out to the other to form a connection.
The server forms the listener socket while the client reaches out to the server.
Socket programming is widely used in instant messaging applications, binary streaming, and document collaborations, online streaming platforms, etc.
Main Functions Provided by <stdio.h>
:
Function | Purpose | ||
---|---|---|---|
printf() |
Prints formatted output to the console | ||
scanf() |
Reads formatted input from the keyboard | ||
getchar() |
Reads a single character from the keyboard | ||
putchar() |
Writes a single character to the screen | ||
gets() |
Reads a string from the keyboard (unsafe) | ||
puts() |
Writes a string to the screen | ||
fopen() |
Opens a file | ||
fclose() |
Closes a file | ||
fread() |
Reads binary data from a file | ||
fwrite() |
Writes binary data to a file | ||
fprintf() |
Prints formatted output to a file | ||
fscanf() |
Reads formatted input from a file |
stdlib
The purpose of <stdlib.h>
(Standard Library Header) in C is to provide functions for general-purpose operations such as:
-
Memory allocation
-
Program control (exit, abort)
-
Conversions (strings to numbers)
-
Random numbers
-
Sorting and searching
🧰 Key Functions in <stdlib.h>
:
Function | Description |
---|---|
malloc() |
Allocates memory dynamically |
calloc() |
Allocates and zero-initializes memory |
realloc() |
Changes size of previously allocated memory |
free() |
Frees dynamically allocated memory |
atoi() |
Converts string to int |
atof() |
Converts string to float (actually returns double ) |
atol() |
Converts string to long int |
strtol() |
Converts string to long with base control |
exit() |
Terminates the program with a return status |
abort() |
Abnormally terminates the program |
rand() |
Generates a random number |
srand() |
Seeds the random number generator |
qsort() |
Sorts an array |
bsearch() |
Performs binary search in a sorted array |
🧰 Common Functions in <string.h>
:
Function | Description |
---|---|
strlen() |
Returns the length of a string |
strcpy() |
Copies one string to another |
strncpy() |
Copies up to n characters |
strcat() |
Appends one string to another |
strncat() |
Appends up to n characters |
strcmp() |
Compares two strings |
strncmp() |
Compares up to n characters |
strchr() |
Finds first occurrence of a character in a string |
strrchr() |
Finds last occurrence of a character in a string |
strstr() |
Finds first occurrence of a substring |
memset() |
Sets a block of memory to a specific value |
memcpy() |
Copies memory block |
memcmp() |
Compares memory blocks |
strtok() |
Splits a string into tokens (based on delimiter) |
unistd.h
The purpose of <unistd.h>
in C is to provide access to the POSIX (Portable Operating System Interface) API, which includes low-level operating system functions for Unix-like systems such as Linux and macOS.
🧰 Key Functions in <unistd.h>
:
Function | Description |
---|---|
read() |
Reads data from a file descriptor |
write() |
Writes data to a file descriptor |
close() |
Closes a file descriptor |
fork() |
Creates a new process (child process) |
exec() family |
Replaces current process image with a new process |
getpid() |
Gets the current process ID |
getppid() |
Gets the parent process ID |
sleep() |
Suspends execution for a given number of seconds |
usleep() |
Sleeps for given microseconds |
chdir() |
Changes the current working directory |
getcwd() |
Gets the current working directory |
access() |
Checks if the file exists or has the right permissions |
pipe() |
Creates a pipe for inter-process communication (IPC) |
dup() , dup2() |
Duplicates file descriptors |
_exit() |
Terminates the process immediately (used after fork() ) |
apra/inet.h
The header file <arpa/inet.h>
in C is used for Internet operations, specifically for handling IP addresses and byte-order conversions in network programming on Unix/Linux systems.
🌐 Purpose:
<arpa/inet.h>
provides functions to:
-
Convert IP addresses between text and binary formats.
-
Convert data between host byte order and network byte order.
⚠️ It is primarily used in socket programming, especially with IPv4 addresses.
Function | Description |
---|---|
inet_addr() |
Converts a dotted-decimal IP string to binary (deprecated) |
inet_aton() |
Converts a dotted-decimal IP string to struct in_addr |
inet_ntoa() |
Converts a binary IP address to dotted-decimal string |
inet_pton() |
Converts IP address from text to binary (IPv4 and IPv6) |
inet_ntop() |
Converts IP address from binary to text (IPv4 and IPv6) |
htons() |
Host to network short (16-bit) byte order |
htonl() |
Host to network long (32-bit) byte order |
ntohs() |
Network to host short |
ntohl() |
Network to host long |
netinet/in.h
The header file <netinet/in.h>
in C is used in network (socket) programming, and it defines constants, structures, and functions needed for Internet domain addresses, especially IPv4 and IPv6 protocols.
⚠️ It's specific to Unix/Linux systems, and part of the POSIX sockets API.
🌐 Purpose of <netinet/in.h>
:
It provides:
-
Definitions for address families like
AF_INET
,AF_INET6
-
Structures for IP addresses and port numbers
-
Constants for protocols (TCP, UDP)
-
Useful macros for working with network addresses
AF_INET // Address family for IPv4
AF_INET6 // Address family for IPv6
IPPROTO_TCP // TCP protocol
IPPROTO_UDP // UDP protocol
sys/socket.h
The header file <sys/socket.h>
in C is used for socket programming. It defines the core socket API, which allows programs to create, configure, and use sockets to communicate over networks.
✅ It is essential for writing any socket-based application in Unix/Linux systems (e.g., TCP, UDP communication).
🎯 Purpose of <sys/socket.h>
It provides:
-
Functions for creating and managing sockets
-
Definitions for socket types and address families
-
Structures and constants used in socket communication
Function | Description |
---|---|
socket() |
Creates a new socket |
bind() |
Binds a socket to an IP address and port |
listen() |
Marks a socket as passive (server) |
accept() |
Accepts a connection from a client |
connect() |
Connects a socket to a remote address (client) |
send() / recv() |
Send/receive data through a socket |
sendto() / recvfrom() |
Send/receive data on a socket (for UDP) |
setsockopt() |
Sets socket options |
getsockopt() |
Gets socket options |
shutdown() |
Disables communication on a socket |
close() |
Closes a socket (defined in <unistd.h> ) |
Constant | Meaning |
---|---|
AF_INET |
Address family for IPv4 |
AF_INET6 |
Address family for IPv6 |
SOCK_STREAM |
TCP (reliable, connection-oriented) |
SOCK_DGRAM |
UDP (unreliable, connectionless) |
SOCK_RAW |
Raw socket (low-level) |
server_fd
(Server File Descriptor)
-
Meaning: File descriptor for the listening socket.
-
Created by:
socket()
function. -
Purpose: This socket listens for incoming client connections.
-
Used in:
bind()
,listen()
, andaccept()
.
📌 client_fd
(Client File Descriptor)
-
Meaning: File descriptor for the connected client socket.
-
Created by:
accept()
function. -
Purpose: This socket is used to communicate with a specific client after the connection is accepted.
-
Used in:
read()
,write()
,send()
,recv()
.📦 What is
struct sockaddr_in
?struct sockaddr_in
is a structure defined in<netinet/in.h>
used specifically for IPv4 addresses.
It holds all the necessary information about an internet socket endpoint.struct sockaddr_in {
sa_family_t sin_family; // Address family (must be AF_INET for IPv4)
in_port_t sin_port; // Port number (must use htons() to convert to network byte order)
struct in_addr sin_addr; // IP address (in network byte order)
char sin_zero[8]; // Padding (unused)
};
struct sockaddr_in server_addr, client_addr;
📦 Why Do We Need a buffer[]
in Socket Code?
Whether you're using TCP or UDP, data is transmitted as raw bytes. The buffer acts like a temporary container for those bytes, either:
-
Coming into your program (received from the network), or
-
Going out to the network (sent to another machine).
Operation Role of buffer[]
recv()
/read()
Store incoming data from the socket send()
/write()
Provide outgoing data to be sent over socket socklen_t addr_len = sizeof(client_addr);
This line is used in socket programming to specify the size of the client address structure (
client_addr
) when calling functions likeaccept()
,recvfrom()
, orgetpeername()
.
server_fd = socket(AF_INET, SOCK_STREAM, 0);
This line is creating a socket and assigning its file descriptor to the variable server_fd
.
The socket()
function returns an integer — a file descriptor that represents the socket.
If it returns -1
, the socket creation failed.
int socket(int domain, int type, int protocol);
Argument | Value | Meaning |
---|---|---|
domain |
AF_INET |
Use IPv4 (Internet Protocol v4) |
type |
SOCK_STREAM |
Use TCP (connection-oriented, reliable) |
protocol |
0 |
Use default protocol for SOCK_STREAM (which is TCP) |
🔧 Socket Types (used as the second argument in socket()
)
Socket Type | Value | Description |
---|---|---|
SOCK_STREAM |
1 |
TCP: Reliable, connection-oriented, stream-based communication (e.g., web browsing). |
SOCK_DGRAM |
2 |
UDP: Unreliable, connectionless, datagram-based communication (e.g., video streaming). |
SOCK_RAW |
3 |
Low-level raw network protocol access (used in tools like ping or traceroute ). |
SOCK_SEQPACKET |
5 |
Like SOCK_STREAM , but preserves message boundaries (used with protocols like SCTP). |
SOCK_RDM |
4 |
Rare: Reliable datagrams (not commonly supported or used). |
Use Case | Recommended Socket Type |
---|---|
HTTP/HTTPS, SSH, FTP | SOCK_STREAM (TCP) |
DNS, VoIP, Video | SOCK_DGRAM (UDP) |
Network tools (ping) | SOCK_RAW |
Message-based file transfer with order | SOCK_SEQPACKET (e.g., SCTP) |
struct sockaddr_in {
short sin_family; // Address family (e.g., AF_INET for IPv4)
unsigned short sin_port; // Port number (in network byte order)
struct in_addr sin_addr; // IP address
char sin_zero[8]; // Padding (not used)
};
sin_family
: Usually set to AF_INET
for IPv4.
sin_port
: Server port (e.g., 8080), converted using htons()
.
sin_addr
: IP address (can be set to INADDR_ANY
for all local interfaces).
sin_zero
: Unused, just padding for structure alignment.
🔗 bind()
– What it does
The bind()
system call associates a socket (created using socket()
) with a specific IP address and port number.
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8080);
server_addr.sin_addr.s_addr = INADDR_ANY;
bind(server_fd, (struct sockaddr*)&server_addr, sizeof(server_addr));
Component | Description | ||
---|---|---|---|
server_addr |
Holds the server’s IP, port, and family info. | ||
Used in | bind() , connect() , accept() , etc. |
||
Structure type | struct sockaddr_in |
||
Typical use | Binding server socket to an IP and port |
Field | Full Meaning | Purpose |
---|---|---|
sin_family |
Socket Internet Family | Specifies IPv4 (AF_INET ) |
sin_port |
Socket Internet Port | Port number (e.g., 8080) |
sin_addr |
Socket Internet Address | Holds the IP address |
sin_addr.s_addr |
Socket Address | Actual 32-bit IP (e.g., 127.0.0.1 ) |
✅ listen()
— What it does:
The listen()
system call puts your server socket into passive mode, meaning:
"I’m ready to accept incoming connections."
int listen(int sockfd, int backlog);
Parameter | Description |
---|---|
sockfd |
The server socket file descriptor (created using socket() and bound using bind() ) |
backlog |
The maximum number of pending connections the OS should queue before refusing new ones |
you're now at the heart of TCP server communication: the accept()
call.
client_fd = accept(server_fd, (struct sockaddr*)&client_addr, &addr_len);
int accept(int server_fd, struct sockaddr *addr, socklen_t *addrlen);
Parameter | Meaning |
---|---|
server_fd |
The listening socket (created by socket() , bound by bind() , and ready via listen() ) |
addr |
Pointer to a sockaddr structure where the client’s info (IP, port) will be stored |
addrlen |
Initially set to size of addr and updated with actual size of client address |
🟡 What is returned?
-
accept()
returns a new socket file descriptor (client_fd
) specific to the connected client. -
You use this new
client_fd
to communicate (read/write) with that client. -
The original
server_fd
keeps listening for other clients.
What recv()
can handle:
-
Text messages
-
Binary data (files, images, etc.)
-
Structured data (with length headers or delimiters)
recv(client_fd, buffer, buffer_size, 0);
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
Parameter Meaning sockfd
Socket file descriptor ( client_fd
) — where you're reading frombuf
Pointer to a buffer where received data will be stored ( buffer
)len
Maximum number of bytes to read ( buffer_size
)flags
Optional flags (usually 0
)Returns Number of bytes received, 0
if client closed connection,-1
on errorsend()
send()
may not send all bytes in one go (in rare network cases). Use a loop for large data.
send(client_fd, msg, strlen(msg), 0);
memset()
memset(buffer, 0, BUFFER_SIZE);
void *memset(void *ptr, int value, size_t num);
Parameter | Meaning |
---|---|
ptr |
Pointer to the memory block (buffer ) |
value |
Value to fill with (0 here, means zeroing out) |
num |
Number of bytes to fill (BUFFER_SIZE ) |
No comments:
Post a Comment