Server Code

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

#define SERV_TCP_PORT 35777
#define SERV_ADDR "165.246.38.151"

struct client {
        char name[20];
        char age[5];
        int partner1;
        int partner2;
};

**struct client cli[50];

void handle_protocol(int x, fd_set * pset, int state[]);

void main(){
   int s1,s2, i, x, y;
   struct sockaddr_in serv_addr, cli_addr;
   char buf[50];
   socklen_t  xx;

   printf("Hi, I am the server\\n");

   bzero((char *)&serv_addr, sizeof(serv_addr));
   serv_addr.sin_family=PF_INET;
   serv_addr.sin_addr.s_addr=inet_addr(SERV_ADDR);
   serv_addr.sin_port=htons(SERV_TCP_PORT);

   //open a tcp socket
   if ((s1=socket(PF_INET, SOCK_STREAM, 0))<0){
      printf("socket creation error\\n");
      exit(1);
   }
   printf("socket opened successfully. socket num is %d\\n", s1);

   // bind ip
   x =bind(s1, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
   if (x < 0){
      printf("binding failed\\n");
      exit(1);
   }
   printf("binding passed\\n");
   listen(s1, 5);
   xx = sizeof(cli_addr);

   // now start ping-pong-pang-pung
   // pset remembers all sockets to monitor
   // rset is the copy of pset passed to select
   fd_set rset, pset;
   int maxfd=50; // just monitor max 50 sockets

   FD_ZERO(&rset); // init rset
   FD_ZERO(&pset); // init pset

   // step 1. monitor conn req packet
   FD_SET(s1, &pset);

   int state[50];
   // and loop on select
   for(i=0;i<20;i++){ // should be infinite loop in real life
      rset=pset;  // step 2
      select(maxfd, &rset, NULL, NULL, NULL); // step 3
      // now we have some packets
      for(x=0;x<maxfd;x++){ // check which socket has a packet
         if (FD_ISSET(x, &rset)){ // socket x has a packet
            // s1 is a special socket for which we have to do "accept"
            // otherwise do ping-pong-pang-pung
            if (x==s1){ // new client has arrived
               // create a socket for this client
               s2 = accept(s1, (struct sockaddr *)&cli_addr, &xx);
               printf("new cli at socket %d\\n",s2);
               FD_SET(s2, &pset); // and include this socket in pset
               state[s2] = 1;
            }else{ // data packet. do ping-pong-pang-pung protocol
               handle_protocol(x, &pset,state);
            }
         }
      }
   }
}**

void handle_protocol(int x, fd_set * pset, int state[]){
// we have a data packet in socket x. do protocol
   int y; char buf[50];
   y=read(x, buf, 50); // read data
   buf[y]=0; // make it a string
   if(state[x]==1){
        handle_state_1(x, pset, buf, state);
   }
   else if(state[x]==2){
        handle_state_2(x, pset, buf, state);
   }
   else if(state[x]==3){
        handle_state_3(x, pset, buf, state);
   }
   else if(state[x]==4){
        handle_state_4(x, pset, buf, state);
   }
   else if(state[x]==5){
        handle_state_5(x, pset, buf, state);
   }
   else if(state[x]==6){
        handle_state_6(x, pset, buf, state);
   }
}

void handle_state_1(int x, fd_set *pset, char *buf, int state[]){
        if(strcmp(buf,"hello") == 0){
                printf("cli at socket %d => serv: %s\\n",x,buf);
                write(x,"name?",5);
                printf("serv => cli at socket %d : name?\\n",x);
                state[x] = 2;
        }
        else{
                printf("received wrong msg from socket %d, disconnecting\\n",x);
                write(x,"protocol error",14);
                close(x);
                FD_CLR(x, pset);
        }
}

void handle_state_2(int x, fd_set * pset, char *buf, int state[]){
        printf("cli %s => serv : %s\\n", buf, buf);
        strcpy(cli[x].name, buf);
        write(x,"ready?",6);
        printf("serv => %s : ready?\\n",cli[x].name);
        state[x] = 3;
}

void handle_state_3(int x, fd_set * pset, char *buf, int state[]){
        if(strcmp(buf,"yes")==0){
                printf("cli %s => serv %s\\n", cli[x].name, buf);
                int i;
                char sbuf[1000];
                strcpy(sbuf,"client name list : ");
                for(i=0;i<50;i++){
                        if(i != x && state[i] >= 3){
                                strcat(sbuf,cli[i].name);
                                strcat(sbuf," ");
                        }
                }
                strcat(sbuf, "");
                write(x,sbuf,strlen(sbuf));
                printf("serv => cli : %s\\n", sbuf);
                state[x] = 4;
        }
        else {
                printf("protocol error from socket %d, disconnecting\\n", x);
                write(x, "protocol error", 14);
                close(x);
                FD_CLR(x, pset);
        }
}

void handle_state_4(int x, fd_set * pset, char *buf, int state[]){
        printf("cli => serv: %s", buf);
        int i;
        for(i=0;i<50;i++){
                if(strcmp(buf,cli[i].name)==0){
                        cli[x].partner1 = i;
                        break;
                }
        }
        state[x]=5;
}

void handle_state_5(int x, fd_set * pset, char *buf, int state[]){
        printf("  %s\\n", buf);
        int i;
        for(i=0;i<50;i++){
                if(strcmp(buf,cli[i].name)==0){
                        cli[x].partner2 = i;
                        break;
                }
        }
        write(x, "go", 2);
        printf("serv => cli: go\\n");
        state[x] = 6;
}

void handle_state_6(int x, fd_set * pset, char *buf, int state[]) {
        int p = cli[x].partner1;
        int q = cli[x].partner2;
        char sbuf[70];
        printf("cli => serv: %s\\n", buf);
        sprintf(sbuf,"%s to (%s and %s) : %s", cli[x].name, cli[p].name, cli[q].name, buf);
        printf("serv => %s and %s: \\"%s\\"\\n", cli[p].name, cli[q].name,sbuf);
        write(p, sbuf, strlen(sbuf));
        write(q, sbuf, strlen(sbuf));
}

Client Code

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

#define SERV_TCP_PORT 35777
#define SERV_ADDR "165.246.38.151"

void main(){
   int x,y;
   struct sockaddr_in serv_addr;
   char buf[50];
   printf("Hi, I am the client\\n");

   bzero((char *)&serv_addr, sizeof(serv_addr));
   serv_addr.sin_family=PF_INET;
   serv_addr.sin_addr.s_addr=inet_addr(SERV_ADDR);
   serv_addr.sin_port=htons(SERV_TCP_PORT);

   //open a tcp socket
   if ((x=socket(PF_INET, SOCK_STREAM, 0))<0){
      printf("socket creation error\\n");
      exit(1);
   }
   printf("socket opened successfully. socket num is %d\\n", x);

   //connect to the server
   if (connect(x, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0){
      printf("can't connect to the server\\n");
      exit(1);
   }
   // now start ping-pong-pang-pung protocol
   int i;
   for(i=0;i<5;i++){
        if(i==0) printf("enter hello\\n");
        gets(buf);
        write(x, buf, strlen(buf));
        y=read(x, buf, 50);
        write(1, buf, y);
        if(i!=3){ printf("\\n"); }
   }

   int z = fork();
   if(z == 0){
        for(i=0;i<30;i++){
                gets(buf);
                write(x, buf, strlen(buf));
        }
   }
   else {
        for(i=0;i<30;i++){
                y = read(x, buf, 50);
                write(1, buf, y);
                printf("\\n");
        }
   }

   close(x);  // disconect the communication
}