Skip to main content

Simple TCP/IP Client Server Example

Socket Programming in C

Socket programming is a method used in network communication that allows data to be sent and received between devices. It is a critical concept in computer networking and is widely used to develop client-server applications.

In this blog post, we will explore the fundamentals of socket programming in C, focusing on TCP (Transmission Control Protocol) for reliable, connection-oriented communication.


What is Socket Programming?

Socket programming enables communication between two nodes on a network. A server listens for incoming client requests, and the client connects to the server to facilitate data exchange.

Sockets provide a communication channel between two processes, either on the same machine or different machines connected via a network.


Types of Sockets

  1. Stream Sockets (SOCK_STREAM):

    • Uses TCP for communication.

    • Provides reliable, connection-oriented communication.

    • Data is transmitted in order and without loss.

  2. Datagram Sockets (SOCK_DGRAM):

    • Uses UDP (User Datagram Protocol).

    • Connectionless and unreliable, but faster.

    • Data may arrive out of order or get lost.

  3. Raw Sockets:

    • Allows direct access to lower-level protocols.

    • Used for packet-level manipulation.


How Socket Communication Works

  1. Server Setup:

    • Create a socket.

    • Bind the socket to an IP address and port.

    • Listen for incoming connections.

    • Accept client connections.

  2. Client Setup:

    • Create a socket.

    • Connect to the server.

  3. Data Exchange:

    • Send and receive data between the server and client.


Server Code

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>

int main() {
    int sockfd, newsock;
    struct sockaddr_in server, client;
    socklen_t len = sizeof(client);
    char buffer[1024];

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons(8080);

    bind(sockfd, (struct sockaddr *)&server, sizeof(server));
    listen(sockfd, 5);
    printf("Waiting for connection...\n");

    newsock = accept(sockfd, (struct sockaddr *)&client, &len);
    read(newsock, buffer, sizeof(buffer));
    printf("Message: %s\n", buffer);

    send(newsock, "Hello from server", 17, 0);
    close(newsock);
    close(sockfd);

    return 0;
}

Client Code

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>

int main() {
    int sockfd;
    struct sockaddr_in server;
    char buffer[1024] = "Hello Server";

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    server.sin_family = AF_INET;
    server.sin_port = htons(8080);
    server.sin_addr.s_addr = inet_addr("127.0.0.1");

    connect(sockfd, (struct sockaddr *)&server, sizeof(server));
    send(sockfd, buffer, strlen(buffer), 0);
    read(sockfd, buffer, sizeof(buffer));
    printf("Response: %s\n", buffer);
    close(sockfd);

    return 0;
}

Output:
$ ./server
Waiting for connection...
Message: Hello Server

$ ./client
Response: Hello from server


How It Works

  1. Server:
  • Creates a socket with socket().
  • Binds to an IP/port with bind().
  • Waits for connections using listen().
  • Accepts incoming connections with accept().
  • Receives and sends data using recv() and send().
  1. Client:
  • Creates a socket with socket().
  • Connects to the server with connect().
  • Sends a message using send().
  • Receives a response from the server.

Testing the Program

  1. Compile the server and client:

    gcc server.c -o server     gcc client.c -o client
  1. Run the server:

    ./server
  1. In another terminal, run the client:

    ./client
  1. The server will receive the message and respond back to the client.

This is a simple TCP server program in C that accepts a client connection, receives a message, and sends a response. Let me break down the key parts of the code for you:

Breakdown of the Code: Server

  1. Headers:


    #include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <arpa/inet.h>
    • These headers include functions for input/output, string manipulation, memory allocation, system calls (like read and write), and network communication.
  2. Socket Creation:


    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    • Creates a TCP socket.
    • AF_INET specifies IPv4, SOCK_STREAM indicates TCP (connection-oriented).
  3. Server Address Structure:


    server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; server.sin_port = htons(8080);
    • sin_family specifies the address family (IPv4).
    • INADDR_ANY allows the server to accept connections on any network interface.
    • htons(8080) converts the port number to network byte order (big-endian).
  4. Binding the Socket:


    bind(sockfd, (struct sockaddr *)&server, sizeof(server));
    • Associates the socket with the IP address and port.
  5. Listening for Connections:


    listen(sockfd, 5);
    • Puts the socket in passive mode to listen for incoming connection requests.
    • 5 specifies the backlog, the number of pending connections allowed.
  6. Accepting a Connection:


    newsock = accept(sockfd, (struct sockaddr *)&client, &len);
    • Accepts the first incoming client connection and creates a new socket (newsock) for communication.
  7. Receiving Data:


    read(newsock, buffer, sizeof(buffer)); printf("Message: %s\n", buffer);
    • Reads data from the client and prints the received message.
  8. Sending a Response:


    send(newsock, "Hello from server", 17, 0);
    • Sends a response back to the client.
  9. Closing Sockets:


    close(newsock); close(sockfd);
    • Closes both the connection socket (newsock) and the listening socket (sockfd).



Breakdown of the Client Code:

  1. Socket Creation:

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    • Creates a TCP socket for the client.
  2. Server Address Structure:


    server.sin_family = AF_INET; server.sin_port = htons(8080); server.sin_addr.s_addr = inet_addr("127.0.0.1");
    • The inet_addr("127.0.0.1") specifies the localhost (server running on the same machine).
    • Change the IP to the server's IP if running on different machines.
  3. Connecting to Server:


    connect(sockfd, (struct sockaddr *)&server, sizeof(server));
    • Connects to the server. The server must be running before this.
  4. Sending Data:


    send(sockfd, buffer, strlen(buffer), 0);
    • Sends a message to the server.
  5. Receiving Response:

    read(sockfd, buffer, sizeof(buffer));
    printf("Message from server: %s\n", buffer);
    • Reads the server’s response and displays it.
  6. Closing Socket:

    close(sockfd);

Notes:

  • Error Handling: This code lacks error handling. Consider adding checks after socket creation, binding, listening, and accepting to ensure smooth operation.
  • Port Selection: Ensure port 8080 is free or change to an available port if needed.
  • Concurrency: This implementation handles one client at a time. For multiple clients, consider using fork() or threads.

Comments

Popular posts from this blog

CSL 332 Networking Lab KTU 2019 Scheme - Dr Binu V P

CSL 332 Networking Lab KTU BTech 2019 Scheme About Me Scheme Syllabus Experiments 1.Learn the Networking Commands and Network Configuration Files     Basic networking commands     More Networking commands     Network configuration Files     View the configuration and address of your network interface     Network Connectivity      View Active TCP connections     MAC address of another machine using ARP  2.  System calls in Network Programming 3.  Simple TCP/IP Client Server Program 4.  Simple UDP Client Server Program 5.Application Programs     Concurrent UDP Time Server     Checking Prime Numbers 6. Simulate ARQ Protocols  / sliding window protocols          Stop and Wait           Go-Back-N          Selective Repeat  7. Routing Protocols - Distance Vector and Link State   ...

Stop and Wait ARQ

Here's a simple C program that demonstrates the Stop-and-Wait ARQ protocol. This basic implementation simulates the sender transmitting packets one at a time and waiting for an acknowledgment from the receiver. If the acknowledgment is not received, the sender retransmits the packet. Key Points: The sender sends one packet at a time. If the receiver acknowledges it (ACK), the sender sends the next packet. If the acknowledgment is lost, the sender retransmits after a timeout. C Program: Stop-and-Wait ARQ Simulation #include <stdio.h> #include <stdlib.h> #include <time.h> #include <unistd.h>  // for sleep() #define TIMEOUT 3  // Timeout duration in seconds #define TOTAL_PACKETS 5  // Number of packets to send int simulate_acknowledgment() {     // Simulate a 70% chance of successful acknowledgment     return rand() % 10 < 7; } int main() {     srand(time(0));  // Seed for random number generation     i...

Server/Client Communication-python

The basic mechanisms of client-server setup are: A client app send a request to a server app.  The server app returns a reply.  Some of the basic data communications between client and server are: File transfer - sends name and gets a file.  Web page - sends url and gets a page.  Echo - sends a message and gets it back.  Client server communication uses socket.              To connect to another machine, we need a socket connection. What's a connection?  A relationship between two machines, where two pieces of software know about each other. Those two pieces of software know how to communicate with each other. In other words, they know how to send bits to each other. A socket connection means the two machines have information about each other, including network location (IP address) and TCP port. (If we can use anology, IP address is the phone number and the TCP port is the extension).  A so...