0% found this document useful (0 votes)
9 views12 pages

Network Programming Answers

The document provides an overview of various concepts in network programming, focusing on TCP socket operations, including the usage of shutdown() and close() functions, and the implementation of a TCP Echo Server. It also discusses I/O multiplexing with pselect(), socket timeouts, and the differences between read()/write() and recv()/send() functions. Additionally, it covers Unix Domain Sockets, the implementation of iterative and concurrent servers, and techniques for passing file descriptors between processes.

Uploaded by

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

Network Programming Answers

The document provides an overview of various concepts in network programming, focusing on TCP socket operations, including the usage of shutdown() and close() functions, and the implementation of a TCP Echo Server. It also discusses I/O multiplexing with pselect(), socket timeouts, and the differences between read()/write() and recv()/send() functions. Additionally, it covers Unix Domain Sockets, the implementation of iterative and concurrent servers, and techniques for passing file descriptors between processes.

Uploaded by

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

Network Programming

Q1. What is the purpose of the shutdown() function in TCP


sockets, and how is it different from close()?

In TCP socket programming, proper connection termination ensures clean


communication and resource management. Two key system calls used are
shutdown() and close().

The shutdown() function allows selective disabling of communication over


a socket. It is used when one end wants to stop sending or receiving data
while keeping the socket open for the other direction. The syntax is:

int shutdown(int sockfd, int how);

 how can be:

o SHUT_RD (0): Disables further reading.

o SHUT_WR (1): Disables further writing.

o SHUT_RDWR (2): Disables both.

The close() function, on the other hand, completely closes the socket
descriptor and releases all associated resources. Once closed, the socket
is no longer usable.

Differences:

Aspect shutdown() close()

Behavio
Partial or full shutdown Full socket closure
r

Resourc Does not free socket Frees file


e immediately descriptor

Graceful, controlled Complete


Usage
termination termination

Example: In a client-server model, the client may send data, then call
shutdown(sockfd, SHUT_WR) to indicate it has finished sending. The
server can continue responding. Later, close() can be used for full closure.

Q2. How do you write a basic TCP Echo Server using the socket
API, and what are its uses and limitations?
A TCP Echo Server is a simple server that sends back whatever data it
receives from the client. It is used to demonstrate TCP bidirectional
communication.

Steps to build a TCP Echo Server:

1. Create a socket using socket().

2. Bind to a port using bind().

3. Listen for connections using listen().

4. Accept incoming client using accept().

5. Read data from the client using recv().

6. Echo the same data back using send().

Sample Code:

int sockfd = socket(AF_INET, SOCK_STREAM, 0);

bind(sockfd, ...);

listen(sockfd, 5);

int clientfd = accept(sockfd, ...);

recv(clientfd, buffer, ...);

send(clientfd, buffer, ...);

Applications:

 Testing network communication

 Educational tool for learning sockets

 Base model for more complex servers

Limitations:

 Handles only one client at a time (iterative)

 Lacks concurrency and error handling

 Not suitable for high-traffic systems

Q3. What is pselect() in I/O multiplexing, and how is it better than


select() for handling signals?

pselect() is a system call used in I/O multiplexing that monitors multiple


file descriptors and allows signal-safe operations, offering an improvement
over select().
Syntax:

int pselect(int nfds, fd_set *readfds, ..., const struct timespec *timeout,
const sigset_t *sigmask);

The sigmask parameter allows atomic signal masking during wait, making
pselect() more suitable for programs that also handle signals.

Comparison with select():

Feature select() pselect()

Signal-safe? No Yes

Timeout Microsecon
Nanoseconds
precision ds

Supported via
Signal masking Not possible
sigmask

Use-case Example: A server that needs to wait for both I/O and a signal
like SIGINT (Ctrl+C) can use pselect() to avoid race conditions.

Advantages:

 Safer with signal handling

 Ideal for real-time systems

 More reliable for event-driven models

Conclusion: pselect() enhances select() by ensuring safe signal handling


during I/O multiplexing. It is preferred in applications that need to respond
to both socket events and asynchronous signals.

Q4. What are socket timeouts, and how can you set read/write
timeouts using setsockopt()?

Socket timeouts define how long a socket operation (like reading or


writing) can block before timing out. This is essential to prevent indefinite
waits during communication failures.

Setting timeouts: Use the setsockopt() function with SO_RCVTIMEO (for


read) and SO_SNDTIMEO (for write) options.

Syntax:

struct timeval tv;

tv.tv_sec = 5; // 5 seconds
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));

Benefits:

 Prevents socket hang due to network issues

 Enhances user experience in real-time systems

 Enables retry or fallback logic in applications

Effect: If the timeout expires, recv() or send() returns -1 and sets errno to
EAGAIN or EWOULDBLOCK.

Use-cases:

 HTTP clients waiting for server responses

 Network devices with unstable connections

 Time-sensitive communication (e.g., games, VoIP)

Q5. How do read()/write() differ from recv()/send() in socket


programming, and when should you use each?

In socket programming, two sets of functions are used for data


transmission: read()/write() (generic file operations) and recv()/send()
(socket-specific).

Key Differences:

Aspec
read()/write() recv()/send()
t

Works on all file


Scope Works only on sockets
descriptors

Supports flags like MSG_PEEK,


Flags No extra control
MSG_DONTWAIT

Simpler, general-
Usage Advanced socket handling
purpose

Syntax:

ssize_t read(int fd, void *buf, size_t count);

ssize_t recv(int sockfd, void *buf, size_t len, int flags);

Use-case:

 Use recv() and send() when advanced options (flags) are required.
 Use read() and write() in simple TCP applications where flags are not
necessary.

Example:

char buffer[100];

recv(sockfd, buffer, sizeof(buffer), MSG_PEEK); // Reads without consuming

Q6. What are readv() and writev() system calls, and how do they
improve I/O efficiency?

readv() and writev() are system calls used for scatter/gather I/O,
allowing multiple buffers to be read from or written to a file/socket in a
single operation.

Syntax:

ssize_t readv(int fd, const struct iovec *iov, int iovcnt);

ssize_t writev(int fd, const struct iovec *iov, int iovcnt);

The iovec structure is defined as:

struct iovec {

void *iov_base; // Pointer to data

size_t iov_len; // Length of data

};

Advantages:

 Minimizes system calls (no repeated read()/write()).

 Increases performance by reducing user-kernel context switches.

 Ideal for applications that separate headers and body (e.g., web
servers).

Example:

char header[] = "Header\n", body[] = "Content\n";

struct iovec iov[2] = {

{header, strlen(header)},

{body, strlen(body)}

};

writev(sockfd, iov, 2);


Use-cases:

 Web servers sending multiple parts (headers + data)

 Logging services

 Protocols with metadata + payload separation

Q7. What is the socket address structure for Unix domain sockets,
and how is it different from INET sockets?

In Unix systems, sockets can communicate over two primary domains:


INET (TCP/IP) and Unix Domain (local IPC). Each uses a different address
structure.

Unix Domain Sockets: Used for inter-process communication on the


same host using file paths instead of IP addresses.

Structure:

struct sockaddr_un {

sa_family_t sun_family; // AF_UNIX

char sun_path[108]; // File path

};

INET Sockets: Used for network communication across machines via


TCP/IP.

Structure:

struct sockaddr_in {

sa_family_t sin_family; // AF_INET

in_port_t sin_port; // Port number

struct in_addr sin_addr;// IP address

};

Comparison:

Unix Domain
Feature INET Sockets
Sockets

Addressing File path IP + Port

Network
Use Local IPC
communication
Unix Domain
Feature INET Sockets
Sockets

Performanc Faster, no TCP/IP Slower, includes


e overhead routing

Example:

sockfd = socket(AF_UNIX, SOCK_STREAM, 0);

struct sockaddr_un addr;

addr.sun_family = AF_UNIX;

strcpy(addr.sun_path, "/tmp/mysocket");

bind(sockfd, (struct sockaddr*)&addr, sizeof(addr));

Q8. What is socketpair() and how can it be used for full-duplex


communication between two processes?

The socketpair() system call creates a pair of connected, unnamed sockets


for two-way communication between related processes (e.g., parent-
child).

Syntax:

int socketpair(int domain, int type, int protocol, int sv[2]);

 Typically used with AF_UNIX, SOCK_STREAM.

 sv[0] and sv[1] are two connected endpoints.

Use-case:

 Inter-process communication (IPC)

 Replacement for pipes with full-duplex capability

Example:

int sv[2];

socketpair(AF_UNIX, SOCK_STREAM, 0, sv);

if (fork() == 0) {

close(sv[0]);

write(sv[1], "Hello", 5);


} else {

close(sv[1]);

char buf[10];

read(sv[0], buf, 10);

Advantages:

 Full-duplex (bi-directional)

 Simpler than using pipe() for both directions

 Local-only, faster than network sockets

Q9. How do you implement a Unix Domain Datagram client/server,


and how is it different from Stream sockets?

Unix Domain Datagram Sockets use the SOCK_DGRAM type for


communication between processes on the same system. Unlike
SOCK_STREAM, they are connectionless and send fixed-sized messages.

Differences:

Featur Datagram Stream


e (SOCK_DGRAM) (SOCK_STREAM)

Type Connectionless Connection-oriented

Delivery Message-based Byte-stream

Orderin
Not guaranteed Guaranteed
g

Use- Continuous data


Simple messaging
case transfer

Server Code (Receiver):

int sockfd = socket(AF_UNIX, SOCK_DGRAM, 0);

struct sockaddr_un addr;

addr.sun_family = AF_UNIX;

strcpy(addr.sun_path, "/tmp/server.sock");
bind(sockfd, (struct sockaddr*)&addr, sizeof(addr));

recvfrom(sockfd, buffer, sizeof(buffer), 0, NULL, NULL);

Client Code (Sender):

int sockfd = socket(AF_UNIX, SOCK_DGRAM, 0);

struct sockaddr_un addr;

addr.sun_family = AF_UNIX;

strcpy(addr.sun_path, "/tmp/server.sock");

sendto(sockfd, "Hello", 5, 0, (struct sockaddr*)&addr, sizeof(addr));

Use-cases:

 Local inter-process notifications

 Lightweight message exchanges

 Simple logging agents

Q10. What is a TCP Iterative Server, and how does it compare to a


Concurrent Server?

A TCP Iterative Server handles one client at a time using a single


process. It accepts a connection, processes it fully, then closes and
accepts the next.

Server Flow:

1. Create socket

2. Bind and listen

3. Accept client

4. Process and respond

5. Close connection and repeat

Example:

while (1) {

clientfd = accept(sockfd, ...);


handle_client(clientfd);

close(clientfd);

Comparison with Concurrent Server:

Iterative
Feature Concurrent Server
Server

Multiple
Clients One at a time
simultaneously

Complexit
Simple Needs fork/threads
y

Scalabilit
Limited High
y

Applications:

 Embedded systems

 Lightweight devices

 Simple services (e.g., Echo server)

Q11. What is a Preforked Server without locking around accept(),


and what issues can it cause?

In a preforked server, multiple child processes are created in advance to


handle incoming clients. Each child calls accept() on the same listening
socket.

Without Locking: When multiple processes call accept() simultaneously


without synchronization, a race condition occurs. Two or more processes
may attempt to accept the same connection.

Issues:

 Lost or delayed connections

 Unpredictable client handling

 Difficult debugging and maintenance


Solutions:

 File Locking: Use fcntl() or flock() around accept() section

 Accept Mutex: Use shared memory or semaphores

 Serialize with Master Process: Let the master accept, and pass
sockets to workers

Sample Lock Implementation:

flock(fd, LOCK_EX);

clientfd = accept(sockfd, ...);

flock(fd, LOCK_UN);

Q12. How can one process send file descriptors to another using
Unix domain sockets?

Descriptor passing allows sending open file descriptors between


processes using Unix Domain Sockets and the sendmsg() / recvmsg()
system calls.

Key Concepts:

 Uses control messages (cmsghdr) and SCM_RIGHTS

 Socket type: AF_UNIX, SOCK_STREAM or SOCK_DGRAM

Sender (Parent Process):

int fds[2];

socketpair(AF_UNIX, SOCK_STREAM, 0, fds);

int fd_to_send = open("file.txt", O_RDONLY);

struct msghdr msg = {0};

char buf[CMSG_SPACE(sizeof(int))];

struct iovec io = {.iov_base = "A", .iov_len = 1};

msg.msg_iov = &io; msg.msg_iovlen = 1;


msg.msg_control = buf;

msg.msg_controllen = CMSG_SPACE(sizeof(int));

struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);

cmsg->cmsg_level = SOL_SOCKET;

cmsg->cmsg_type = SCM_RIGHTS;

cmsg->cmsg_len = CMSG_LEN(sizeof(int));

memcpy(CMSG_DATA(cmsg), &fd_to_send, sizeof(int));

sendmsg(fds[0], &msg, 0);

Receiver (Child Process):

struct msghdr msg = {0};

char buf[CMSG_SPACE(sizeof(int))];

struct iovec io = {.iov_base = "B", .iov_len = 1};

msg.msg_control = buf;

msg.msg_controllen = sizeof(buf);

msg.msg_iov = &io; msg.msg_iovlen = 1;

recvmsg(fds[1], &msg, 0);

struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);

int received_fd = *(int *)CMSG_DATA(cmsg);

You might also like