0% found this document useful (0 votes)
0 views18 pages

Network Programming Notes Module-02

Uploaded by

Minhaj Choudhry
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
0 views18 pages

Network Programming Notes Module-02

Uploaded by

Minhaj Choudhry
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 18

Module-02

Sockets Introduction – socket address structures, value-result arguments,


byte ordering and manipulation functions,address conversion functions,
Elementary TCP Sockets – socket, connect, bind, listen, accept , fork and
concurrent server design, getcsockname and getpeername functions and
TCP Client/Server Example.

1. Sockets Introduction:
Socket in Computer Network
A socket is one endpoint of a two way communication link between two
programs running on the network. The socket mechanism provides a means of
inter-process communication (IPC) by establishing named contact points
between which the communication take place.

How Sockets Work in Computer Networks


Like 'Pipe' is used to create pipes and sockets is created using 'socket' system
call. The socket provides bidirectional FIFO Communication facility over the
network.
 A socket connecting to the network is created at each end of the
communication.
 Each socket has a specific address.
 This address is composed of an IP address and a port number.
 Socket are generally employed in client server applications.
 The server creates a socket, attaches it to a network port addresses then
waits for the client to contact it.
 The client creates a socket and then attempts to connect to the server
socket.
 When the connection is established, transfer of data takes place.

Types of Sockets
There are two types of Sockets:
 Datagram Socket : This is a type of network which has connection less
point for sending and receiving packets. It is similar to mailbox. The
letters (data) posted into the box are collected and delivered (transmitted)
to a letterbox (receiving socket).
 Stream Socket In Computer operating system, a stream socket is type
of interprocess communications socket or network socket which
provides a connection-oriented, sequenced, and unique flow of data
without record boundaries with well defined mechanisms for creating
and destroying connections and for detecting errors. It is similar to
phone. A connection is established between the phones (two ends) and a
conversation (transfer of data) takes place.
 Common Function Calls in Socket Programming
 Here is a summary of the common function calls used in socket
programming:
Function Call Description

Socket() To create a socket

Bind() It's a socket identification like a telephone number to


Function Call Description

contact

Listen() Ready to receive a connection

Connect() Ready to act as a sender

Confirmation, it is like accepting to receive a call


Accept()
from a sender

Write() To send data

Read() To receive data

Close() To close a connection

2. Socket Address Structure:

A socket address structure is a data structure used by socket


functions to identify network endpoints. It contains information like
the address family, port number, and the actual address (e.g., IPv4 or
IPv6 address). Different protocols have their own specific address
structures, but all can be represented by a generic sockaddr structure.
Here's a more detailed breakdown:
Key Components:
sa_family:
Specifies the address family (e.g., AF_INET for IPv4, AF_INET6 for
IPv6, AF_UNIX for Unix domain sockets).
sa_data or protocol-specific fields:
This field holds the actual address information, which varies depending
on the address family. For example, in IPv4, it would include the IP
address and port number.
sockaddr_in (IPv4):
A specific structure for IPv4 addresses,
containing sin_family, sin_port (port number), sin_addr (IPv4 address),
and padding.
sockaddr_in6 (IPv6):
Similar to sockaddr_in, but for IPv6 addresses.
sockaddr_un (Unix domain sockets):
Used for communication between processes on the same machine,
containing sun_family and sun_path (the path to the socket).
sockaddr_storage:
A generic structure that can hold any type of socket address. It's used
when a function needs to handle addresses from different families.

Example:
Consider an IPv4 socket. Its address is represented by
the sockaddr_in structure, which includes:
struct sockaddr_in {
sa_family_t sin_family; // Address family (AF_INET)
in_port_t sin_port; // Port number
struct in_addr sin_addr; // IPv4 address
unsigned char sin_zero[8]; // Padding to make structure same size as
sockaddr
};
How it's used:
 Socket functions like bind, connect, accept, and sendto take
a sockaddr (or a pointer to a protocol-specific structure) as an argument.
 The application provides the socket address structure to these functions,
which then use it to establish connections, send data, or receive data
from the specified address.
 When working with different address families, applications often need
to cast the generic sockaddr pointer to the correct protocol-specific
structure (e.g., sockaddr_in for IPv4).
 In essence, socket address structures are the fundamental way that
applications identify and interact with network endpoints.

3. value-result arguments:
In network programming, a value-result argument is a parameter passed to a
function where the function both receives an initial value from the caller and
returns a modified value back to the caller. This is particularly useful in socket
programming where you need to pass a socket address structure and its length,
and the function needs to both receive the initial size of the buffer (for receiving
data) and return the actual size of the data received.
Here's a breakdown:
Value:
The initial value of the argument is used by the function. For example, when
calling getpeername() to retrieve the address of a connected peer, you pass the
size of your buffer as an argument.
Result:
The function modifies the argument and returns the updated value. In
the getpeername() example, the function modifies the length argument to
reflect the actual size of the peer's address that was received.
Example:
accept() in socket programming is a prime example. You pass the size of
your sockaddr_in structure to accept(). The function then fills the structure
with the client's address and updates the length argument with the actual size
of the address.
Why use it?
Value-result arguments are convenient because they allow a single parameter
to convey both input and output information to the function, avoiding the need
for separate input and output parameters or return values.
In simpler terms, imagine you have a container (the argument) and you want a
function to fill it with something, but you also need to know how much was
actually put in the container. You pass the empty container (its size) and the
function returns the filled container (and the updated size).
4. byte ordering and manipulation functions:
In network programming, byte ordering (also known as endianness) and
manipulation functions are crucial for ensuring that multi-byte data is
interpreted correctly when transmitted between systems with different
architectures. Network protocols generally use big-endian byte order, while
many systems (like Intel x86) use little-endian. Functions
like htons, htonl, ntohs, and ntohl are used to convert between host and
network byte order, preventing data corruption during communication.
Byte Ordering:
Big-Endian: Stores the most significant byte at the lowest memory address.
Little-Endian: Stores the least significant byte at the lowest memory
address.
Network Byte Order:
Network protocols, like TCP/IP, typically use big-endian byte order for
transmitting multi-byte data like port numbers, IP addresses, and other
network-related information.
Byte Ordering Functions:
htons(hostshort): Converts a 16-bit (2-byte) quantity from host byte order to
network byte order (big-endian).
htonl(hostlong): Converts a 32-bit (4-byte) quantity from host byte order to
network byte order (big-endian).
ntohs(netshort): Converts a 16-bit quantity from network byte order to host
byte order.
ntohl(netlong): Converts a 32-bit quantity from network byte order to host
byte order.
Byte Manipulation Functions:
memcpy(dest, src, n): Copies n bytes from the memory location pointed to
by src to the memory location pointed to by dest.
memset(dest, c, n): Fills the first n bytes of the memory location pointed to
by dest with the byte value c.
memcmp(ptr1, ptr2, n): Compares the first n bytes of the memory locations
pointed to by ptr1 and ptr2.
bcopy(src, dest, n): Copies n bytes from src to dest.
bzero(dest, n): Sets the first n bytes of the memory location pointed to
by dest to 0.
bcmp(ptr1, ptr2, n): Compares the first n bytes of the memory locations
pointed to by ptr1 and ptr2.
Why are these functions important?

Using these functions ensures that data is interpreted consistently across


different systems, regardless of their native byte order. For example, if a
client with a little-endian architecture sends a 16-bit port number to a server
with a big-endian architecture, the htons function on the client side would
convert the port number to big-endian before sending it. The server would
then use ntohs to convert it back to its native byte order for proper
interpretation. This prevents misinterpretations and ensures correct
communication between the client and server.

5. Address conversion functions:


In network programming, address conversion functions are crucial for
translating between human-readable text representations of IP addresses (like
"192.168.1.1") and their binary formats used internally by computers. These
functions are essential for tasks such as configuring network interfaces,
establishing connections, and displaying IP addresses in a user-friendly way.
Common Address Conversion Functions:
 inet_pton (Protocol to Numeric):
Converts an IP address from text format (e.g., "192.168.1.1" or
"2001:db8::1") to its binary representation in network byte order. It supports
both IPv4 and IPv6 addresses.
 inet_ntop (Numeric to Protocol):
Converts a binary IP address (in network byte order) back to its text
representation. Like inet_pton, it supports both IPv4 and IPv6.
 inet_addr (IPv4 only):
Converts an IPv4 address in dotted-decimal notation to a 32-bit binary
value.
 inet_aton (IPv4 only):
Converts an IPv4 address in dotted-decimal notation to a 32-bit binary value
and stores it in a structure.
 inet_ntoa (IPv4 only):
Converts a 32-bit IPv4 address to its dotted-decimal representation.
Example:
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main() {
const char *ipv4_address_str = "192.168.1.100";
struct in_addr ipv4_addr;

// Convert IPv4 address string to binary


if (inet_pton(AF_INET, ipv4_address_str, &ipv4_addr) <= 0) {
perror("inet_pton failed");
return 1;
}

printf("Binary IPv4 address: %x\n", ipv4_addr.s_addr);

char buffer[INET_ADDRSTRLEN];
// Convert binary IPv4 address to string
if (inet_ntop(AF_INET, &ipv4_addr, buffer, INET_ADDRSTRLEN) ==
NULL) {
perror("inet_ntop failed");
return 1;
}
printf("String IPv4 address: %s\n", buffer);

return 0;
}
Key Considerations:
 IPv4 vs. IPv6:
inet_pton and inet_ntop are the preferred functions as they handle both IPv4
and IPv6 addresses.
 Network Byte Order:
Address conversion functions typically operate in network byte order (big-
endian), which is the standard for network communication.
 Error Handling:
Always check the return values of these functions to ensure successful
address conversion and handle errors appropriately
6.Elementary TCP sockets:
Elementary TCP sockets in network programming involve a set of system
calls that enable communication between applications over a network using
the Transmission Control Protocol (TCP). These calls handle the creation,
connection, data transfer, and termination of TCP connections.
Here's a breakdown of the key concepts and functions:
1. Socket Creation:
 socket(): This function is the first step in creating a socket. It takes
parameters specifying the address family (e.g., AF_INET for IPv4),
socket type (e.g., SOCK_STREAM for TCP), and protocol (usually 0 for
TCP). It returns a file descriptor (an integer) that represents the socket.
2. Server-Side Operations:
 bind(): This function associates a local address (IP address and port
number) with the socket. Servers typically bind to a well-known port that
clients can connect to.
 listen(): This function puts the server socket into a passive listening state,
indicating that it's ready to accept incoming connection requests.
 accept(): This function blocks until a client connects to the server's
socket. It then creates a new socket (a "connected socket") for
communication with that specific client, returning a new file descriptor.
3. Client-Side Operations:
 connect(): This function initiates a connection to a server. It takes the
server's address information as input and attempts to establish a TCP
connection.
4. Data Transfer:
 read(): This function reads data from a connected socket.
 write(): This function sends data to a connected socket.
5. Connection Termination:
close(): This function closes the socket, releasing the associated
resources.
Example Scenario:
A TCP server would typically:
1. Create a socket using socket().
2. Bind the socket to a specific address and port using bind().
3. Put the socket into a listening state using listen().
4. Enter a loop:
o Accept a connection using accept().
o Communicate with the client using read() and write().
o Close the connected socket using close().
Fig: Elementary TCP sockets

A TCP client would typically:


1. Create a socket using socket().
2. Connect to the server using connect().
3. Communicate with the server using read() and write().
4. Close the socket using close().
Key Concepts:
 Connection-oriented:
TCP is connection-oriented, meaning a connection must be established
before data can be exchanged.
 Reliable:
TCP provides reliable data delivery, ensuring that data arrives in the
correct order and without errors.
 Stream-based:
TCP transmits data as a continuous stream of bytes, without message
boundaries.
By understanding these elementary socket functions and concepts, you
can build robust and reliable network applications using TCP.

7.Elementary TCP Sockets – socket, connect, bind, listen, accept:


In TCP socket programming, several key functions are used to establish and
manage connections between clients and servers. These functions, in order of
operation, are socket, bind, listen, accept, and connect. socket creates a socket
endpoint, bind associates a local address with the socket, listen prepares the
server to accept incoming connections, accept handles incoming connection
requests, and connect allows a client to initiate a connection to a server.
Here's a breakdown of each function:
1. socket():
 Purpose: Creates a new socket, returning a file descriptor that represents
the socket.
 Arguments: Specifies the address family (e.g., AF_INET for IPv4),
socket type (e.g., SOCK_STREAM for TCP), and protocol (usually 0 for
TCP).
 Return value: An integer representing the socket descriptor, or -1 on
error.
2. bind():
 Purpose: Associates a local address (IP address and port number) with a
socket.
 Arguments: Takes the socket descriptor, a pointer to a sockaddr structure
containing the address information, and the size of the address structure.
 Return value: 0 on success, -1 on error.
 Note: Clients usually don't need to explicitly bind, as the system will
automatically assign an available port. Servers typically bind to a specific
port they will listen on.
3. listen():
 Purpose:
(Server-side only) Sets the socket to listen for incoming connection requests.
 Arguments:
Takes the socket descriptor and a backlog value (the maximum length of the
queue of pending connections).
 Return value:
0 on success, -1 on error.
 Note:
This function is crucial for servers to indicate their readiness to accept
connections from clients.
4. accept():
 Purpose:
(Server-side only) Accepts an incoming connection request from the queue and
creates a new socket for communication with the client.
 Arguments:
Takes the listening socket descriptor, a pointer to a sockaddr structure (to store
the client's address), and a pointer to the size of the address structure.
 Return value:
A new socket descriptor for the established connection, or -1 on error.
 Note:
The listening socket remains open to accept more connections, while the new
socket handles the communication with the specific client.
5. connect():
 Purpose: (Client-side only) Initiates a connection to a server.
 Arguments: Takes the client's socket descriptor, a pointer to
a sockaddr structure containing the server's address, and the size of the
address structure.
 Return value: 0 on success, -1 on error (e.g., connection refused,
timeout).
 Note: This function triggers the TCP handshake to establish the
connection.
8.fork and concurrent server design:

A concurrent server handles multiple client requests simultaneously, and one


common way to implement this is by using the fork() system call in Unix-
like systems. The fork() function creates a new process (child) that is a copy
of the original process (parent). In a concurrent server, the parent process
listens for new client connections, and upon receiving one, it forks() a child
process to handle that specific connection. The parent then continues to
listen for new connections, allowing the server to handle multiple clients
concurrently.
Here's a breakdown of the process:
1. Server Initialization:
The server starts by creating a listening socket and binding it to a specific
port.
2. Listening for Connections:
The server then enters a loop, listening for incoming connection requests on
the listening socket.
3. Accepting Connections:
When a client attempts to connect, the accept() function returns a new socket
descriptor for that specific connection. The server then has a connection
socket (connfd) and the listening socket (listenfd).
4. Forking a Child Process:
The server calls the fork() function. fork() returns twice: once in the parent
process (with the child's process ID), and once in the newly created child
process (with a return value of 0).
5. Handling the Client:
 The parent process closes the newly created connection socket
(connfd) as the child will handle the client. The parent then
continues to listen for new connections.
 The child process handles the communication with the specific
client connected to the connfd. This might involve receiving data,
processing it, and sending back a response.
6. Concurrency:
By forking a new process for each client, the server can handle multiple
clients concurrently. While one child process is busy handling a client, the
parent process can accept new connections from other clients.
Benefits of using fork() for concurrent servers:
 Simplicity: fork() is a relatively straightforward way to create a
concurrent server.
 Isolation: Each child process has its own memory space, providing
isolation between clients.
 Concurrency: The server can handle multiple clients simultaneously.
Considerations when using fork():
 Resource Usage:
Creating a new process for each client can be resource-intensive, especially
with a large number of concurrent connections.
 Zombie Processes:
If the parent process doesn't handle the termination of its child processes,
they can become zombie processes, which can lead to resource
exhaustion. The SIGCHLD signal can be used to handle child process
termination and prevent this.
 Alternative Approaches:
While fork() is a common approach, other methods like using threads or I/O
multiplexing (e.g., select(), poll(), epoll()) can also be used for concurrent
server design and may be more efficient in some cases.

9.getcsockname and getpeername functions:

In network programming, getsockname and getpeername are two socket


functions used to retrieve information about a socket's local and remote
addresses, respectively. getsockname returns the local address bound to the
socket, while getpeername returns the address of the peer (remote endpoint)
connected to the socket.
getsockname():
 Purpose: Retrieves the local address associated with a socket.
 Usage: Typically used to discover the port number assigned to a socket
after it's been bound (either explicitly or implicitly through connect()).
 Return Value: Returns 0 on success, -1 on failure, and sets errno to
indicate the error.
 Example: If a client connects to a server without explicitly binding to a
port, getsockname() can be used to determine the dynamically assigned
port number after the connection is established.
getpeername():
 Purpose:
Retrieves the address of the peer (remote endpoint) connected to the socket.
 Usage:
Useful for identifying the remote host and port after a connection has been
established using connect() or accept().
 Return Value:
Returns 0 on success, -1 on failure, and sets errno to indicate the error.
 Example:
On a server, after accepting a connection with accept(), getpeername() can be
used to get the client's address.
Key Differences:
 getsockname() retrieves the local address of the socket,
while getpeername() retrieves the remote address.
 getsockname() is often used after a bind() or connect() call,
while getpeername() is typically used after an accept() or connect() call.
 getsockname() can return the dynamically assigned port number after
a connect() call, even if the client didn't explicitly bind to a port.
In essence: getsockname() tells you who you are on the network,
while getpeername() tells you who you are talking to.

10.TCP Client/Server Example:

A TCP client/server example in network programming involves two programs: a


server that listens for connections and a client that initiates a connection to the
server. The server accepts the client's connection, and then both the client and
server can exchange data using TCP sockets. A common example is an echo
server, where the server receives data from the client and sends it back.
Server-side (example in Python):
import socket
HOST = '127.0.0.1' # Standard loopback interface address (localhost)
PORT = 65432 # Port to listen on (non-privileged ports are > 1023)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
s.listen()
conn, addr = s.accept()
with conn:
print(f"Connected by {addr}")
while True:
data = conn.recv(1024)
if not data:
break
conn.sendall(data)
Client-side (example in Python):
import socket

HOST = '127.0.0.1' # The server's hostname or IP address


PORT = 65432 # The port used by the server

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:


s.connect((HOST, PORT))
s.sendall(b'Hello, world')
data = s.recv(1024)

print(f'Received {data!r}')
Explanation:
 Sockets:
Sockets are the endpoints of a two-way communication link between programs.
 TCP:
TCP (Transmission Control Protocol) is a connection-oriented protocol that
ensures reliable, ordered, and error-checked delivery of data.
 Client-Server Model:
The server listens for incoming connections on a specific port, while the client
initiates a connection to that port.
 Connection Establishment:
The server uses bind() to associate the socket with a specific address and
port, listen() to wait for incoming connections, and accept() to accept a
connection.
 Data Exchange:
Once connected, the client and server can use sendall() to send data
and recv() to receive data.
 Echo Server:
In this example, the server simply sends back whatever it receives,
demonstrating a basic data exchange.

You might also like