How to Write a TCP Echo Server in C

In c you are as close to the metal - or at least as close to the os - as possible in a high-level language. This shows in the verbose code you need to make a simple tcp server which echos messages back to the client. Furthermore this implementation of the server will only ever accept one client - and when that client disconnects, the program exits.

Suffice to say these 89 lines of code does not give a lot of versatility - but it shows exactly which system calls are needed to make a tcp server - and all other implementations will make the exact same system calls - but will package them much more nicely for us.

#include <stdlib.h> //atoi
#include<stdio.h>
#include<string.h>  //strlen
#include<sys/socket.h>
#include<arpa/inet.h>   //inet_addr
#include<unistd.h>  //write

int socket_desc , client_sock , c , read_size;
struct sockaddr_in server , client;
char client_message[2000];

void setup_socket()
{
    // This creates the socket - or quits
    socket_desc = socket(AF_INET , SOCK_STREAM , 0);
    if (socket_desc == -1)
    {
        printf("Could not create socket");
        exit(2);
    }
    puts("Socket created");
}

void setup_server_address(int port) {
    //Prepare the sockaddr_in structure
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons( port );
}

void bind_socket_to_server_address() {
    //Bind
    if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
    {
        //print the error message
        perror("bind failed. Error");
        exit(1);
    }
    puts("bind done");
}

void listen_to_socket() {
    //Listen
    listen(socket_desc , 3);

    //Accept and incoming connection
    puts("Waiting for incoming connections...");
    c = sizeof(struct sockaddr_in);
}

int main(int argc , char *argv[])
{
  int port = atoi(argv[1]);

  setup_socket();
  setup_server_address(port);
  bind_socket_to_server_address();
  listen_to_socket();


  //accept connection from an incoming client
  client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);

  if (client_sock < 0)
  {
    perror("accept failed");
    return 1;
  }
  puts("Connection accepted");

  //Receive a message from client
  while( (read_size = recv(client_sock , client_message , 2000 , 0)) > 0 )
  {
    //Send the message back to client
    write(client_sock , client_message , strlen(client_message));
  }

  if(read_size == 0)
  {
    puts("Client disconnected");
    fflush(stdout);
  }
  else if(read_size == -1)
  {
    perror("recv failed");
  }

    return 0;
}

Related Posts