Architecture Diagram
+------------+ +-----------+
| Client | <------> | Server |
+------------+ +-----------+
^ ^
| stdin | stdin
v v
+----------+ +----------+
| User | | User |
| Input | | Input |
+----------+ +----------+Server Implementation Breakdown
Server Code Structure
#include <sys/socket.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <poll.h>
#include <unistd.h>
int main() {
// Socket creation and setup
// Main loop with poll()
// Communication handling
return 0;
}Step-by-Step Explanation
Step 1: Create Socket
int sockfd = socket(AF_INET, SOCK_STREAM, 0);AF_INET: IPv4 address familySOCK_STREAM: TCP socket type- Returns file descriptor for the socket
Step 2: Bind Socket
struct sockaddr_in address = {
AF_INET,
htons(9999),
0
};
bind(sockfd, &address, sizeof(address));htons(9999): Convert port number to network byte order0in address field means bind to all interfaces
Step 3: Listen for Connections
listen(sockfd, 10);- Backlog of 10 pending connections
- Server is now waiting for client connections
Step 4: Accept Client Connection
int clientfd = accept(sockfd, 0, 0);- Blocks until client connects
- Returns new file descriptor for client communication
Step 5: Setup poll() Structure
struct pollfd fds[2] = {
{0, POLLIN, 0}, // stdin
{clientfd, POLLIN, 0} // client socket
};- Monitor 2 file descriptors:
- Standard input (keyboard)
- Client socket
Step 6: Main poll() Loop
for (;;) {
char buffer[256] = {0};
poll(fds, 2, 50000);
// Handle events...
}poll()waits for 50 seconds (50000 milliseconds)- Checks for input from either source
Step 7: Handle Input Events
if (fds[0].revents & POLLIN) { // stdin input
read(0, buffer, 255);
send(clientfd, buffer, 255, 0);
}
else if (fds[1].revents & POLLIN) { // client message
if (recv(clientfd, buffer, 255, 0) == 0) return 0;
printf("%s\n", buffer);
}- Forward stdin input to client
- Print received messages from client
Client Implementation Breakdown
Client Code Structure
#include <sys/socket.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <poll.h>
#include <unistd.h>
int main() {
// Socket creation and connection
// Main loop with poll()
// Communication handling
return 0;
}Step-by-Step Explanation
Step 1: Create Socket
int sockfd = socket(AF_INET, SOCK_STREAM, 0);- Same as server socket creation
Step 2: Connect to Server
struct sockaddr_in address = {
AF_INET,
htons(9999),
0
};
connect(sockfd, &address, sizeof(address));- Connect to server at port 9999
0in address field means localhost (127.0.0.1)
Step 3: Setup poll() Structure
struct pollfd fds[2] = {
{0, POLLIN, 0}, // stdin
{sockfd, POLLIN, 0} // server socket
};- Similar to server's poll setup
Step 4: Main poll() Loop
for (;;) {
char buffer[256] = {0};
poll(fds, 2, 50000);
// Handle events...
}- Same logic as server's main loop
Step 5: Handle Input Events
if (fds[0].revents & POLLIN) { // stdin input
read(0, buffer, 255);
send(sockfd, buffer, 255, 0);
}
else if (fds[1].revents & POLLIN) { // server message
if (recv(sockfd, buffer, 255, 0) == 0) return 0;
printf("%s\n", buffer);
}- Mirror of server's message handling
Communication Flow Diagram
Client Process Server Process
| |
|-------- TCP Connection ---------->|
| |
|------- stdin Input -------------->|
|<----- Received Message -----------|
| |
|<----- stdin Input ----------------|
|------- Received Message --------->| Key Concepts Explained
poll() System Call
+----------------+
| poll() |
+----------------+
| | +------------+
| File Descriptors <----| stdin (0) |
| | | socket fd |
+----------------+ +------------+
|
v
+---------------+
| Event Checking|
| POLLIN |
| POLLOUT |
| etc. |
+---------------+- Monitors multiple file descriptors simultaneously
- Returns when any fd is ready for I/O
- More efficient than busy-waiting
Network Byte Order
Host Byte Order (e.g., 1234) -> htons() -> Network Byte Order (e.g., 3412)
Network Byte Order (e.g., 3412) -> ntohs() -> Host Byte Order (e.g., 1234)- Ensures consistent data representation across different architectures
- Critical for port numbers and IP addresses
Execution Flow
- Start server first:
./server- Start client in another terminal:
./client- Communication test:
- Type message in server terminal -> appears in client
- Type message in client terminal -> appears in server
Important Notes
- Port Number: Both use port 9999 (ensure it's available)
- Localhost Only:
0in address field binds to all interfaces - Buffer Size: Fixed 256-byte buffer (255 chars + null terminator)
- Blocking Behavior:
poll()with 50s timeout prevents busy-waiting
Limitations and Improvements
- Single Client: Server handles only one connection at a time
- No Error Handling: Add checks for socket/bind/listen errors
- Message Truncation: Messages over 255 bytes will be split
- Exit Condition: Closing connection terminates both ends
Full Code with Comments
server.c (Enhanced Comments)
#include <sys/socket.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <poll.h>
#include <unistd.h>
int main() {
// Create TCP socket
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
// Configure server address
struct sockaddr_in address = {
AF_INET, // IPv4
htons(9999), // Port
0 // Listen on all interfaces
};
// Bind socket to address
bind(sockfd, (struct sockaddr*)&address, sizeof(address));
// Start listening
listen(sockfd, 10);
// Accept incoming connection
int clientfd = accept(sockfd, 0, 0);
// Configure poll structure
struct pollfd fds[2] = {
{0, POLLIN, 0}, // stdin
{clientfd, POLLIN, 0} // client socket
};
// Main communication loop
for (;;) {
char buffer[256] = {0};
// Wait for events (50s timeout)
poll(fds, 2, 50000);
// Handle stdin input
if (fds[0].revents & POLLIN) {
read(0, buffer, 255);
send(clientfd, buffer, 255, 0);
}
// Handle client message
else if (fds[1].revents & POLLIN) {
if (recv(clientfd, buffer, 255, 0) == 0) {
// Connection closed
return 0;
}
printf("Received: %s\n", buffer);
}
}
return 0;
}client.c (Enhanced Comments)
#include <sys/socket.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <poll.h>
#include <unistd.h>
int main() {
// Create TCP socket
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
// Configure server address
struct sockaddr_in address = {
AF_INET, // IPv4
htons(9999), // Port
0 // Connect to localhost
};
// Connect to server
connect(sockfd, (struct sockaddr*)&address, sizeof(address));
// Configure poll structure
struct pollfd fds[2] = {
{0, POLLIN, 0}, // stdin
{sockfd, POLLIN, 0} // server socket
};
// Main communication loop
for (;;) {
char buffer[256] = {0};
// Wait for events (50s timeout)
poll(fds, 2, 50000);
// Handle stdin input
if (fds[0].revents & POLLIN) {
read(0, buffer, 255);
send(sockfd, buffer, 255, 0);
}
// Handle server message
else if (fds[1].revents & POLLIN) {
if (recv(sockfd, buffer, 255, 0) == 0) {
// Connection closed
return 0;
}
printf("Received: %s\n", buffer);
}
}
return 0;
}References & Further Reading
Essential Socket Programming Resources:
-
"UNIX Network Programming" by W. Richard Stevens
The definitive guide to network programming in UNIX environments -
"Beej's Guide to Network Programming" (Free Online Resource)
https://beej.us/guide/bgnet/
Excellent beginner-friendly tutorial on socket programming -
Linux Manual Pages
Useman 2 socket,man 2 bind,man pollin terminal
Official Linux system call documentation -
"The Linux Programming Interface" by Michael Kerrisk
Comprehensive guide to Linux system programming -
GNU C Library Documentation
https://www.gnu.org/software/libc/manual/
Official C standard library documentation
Support & Contact
☕ Support the Developer
If you found this guide helpful, consider supporting my work:
buymeacoffee.com/trish07
🐦 Connect on Twitter/X
For updates and programming tips follow :
Trish & Paul
Learning Path Recommendation
Visual roadmap from basic sockets to advanced network protocols
Path Explanation
- Socket Basics: Understand fundamental socket APIs
- TCP Client/Server: Master connection-oriented communication
- Multiplexing: Learn efficient I/O handling with poll()/select()
- Multi-client: Scale to handle concurrent connections
- Advanced Protocols: Implement TLS, HTTP, or custom protocols
This visual roadmap helps you:
- Track your progress through networking concepts
- Understand prerequisite relationships between topics
- Identify key milestones in network programming
For any questions or queries, feel free to reach out!
