#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define PORT 1234
 
int main(int argc, char **argv)
{
  struct sockaddr_in sock_addr;
  int sockfd, connectedfd;

  fprintf(stdout,"Server: creating socket\n");
  sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
  if (sockfd == -1) { 
    perror("socket()");
    exit(1);
  }
 
  memset(&sock_addr, 0, sizeof(sock_addr));
 
  sock_addr.sin_family = AF_INET;
  sock_addr.sin_port = htons(PORT);
  sock_addr.sin_addr.s_addr = INADDR_ANY;
 
  fprintf(stdout,"Server: binding socket to port %d\n",PORT);
  if(bind(sockfd,(const void *)&sock_addr, sizeof(sock_addr)) == -1) {
    perror("bind()");
    close(sockfd);
    exit(1);
  }
 
  fprintf(stdout,"Server: listening on socket\n");
  if(listen(sockfd, 10) == -1) {
    perror("listen()");
    close(sockfd);
    exit(1);
  }
 
  fprintf(stdout,"Server: accepting connection\n");
  connectedfd = accept(sockfd, NULL, NULL);

  if(connectedfd == -1) {
    perror("accept()");
    close(sockfd);
    exit(1);
  }
 
   /* perform read write operations ... */
  char buffer[128];

  fprintf(stdout,"Server: reading from the socket\n");
  if (read(connectedfd, buffer, 128) == -1) {
    perror("read()");
    close(sockfd);
    close(connectedfd);
    exit(1);
  }
  fprintf(stdout,"Server received message: '%s'\n",buffer);
  sprintf(buffer,"got it");
  fprintf(stdout,"Server: writing to the socket\n");
  if (write(connectedfd, buffer, 1+strlen(buffer)) == -1) {
    perror("write()");
    close(connectedfd);
    exit(1);
  }
 
  fprintf(stdout,"Server: shutting down socket\n");
  if (shutdown(connectedfd, SHUT_RDWR) == -1) {
    perror("shutdown()");
    close(connectedfd);
    exit(1);
  }

  close(connectedfd);

  exit(0);
}
