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
}