Click here to Skip to main content
15,885,366 members
Please Sign up or sign in to vote.
1.00/5 (2 votes)
See more:
Hello everyone, I am doing a project in the programming language c.
I created a chat that clients can talk to each other using the server.
I want to connect all the clients to another server and when they leave one server they will go straight to the other server, which means I wanted them to log in with a certain condition to the other server (say with a certain if).
The problem is that I really do not know how to do it I would be very happy to help create the second server. And how exactly do I run the second server in Linux.
Many thanks to the helpers.
mor levi

What I have tried:

my client code:
C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <sys types.h="">
#include <sys socket.h="">
#include <netinet in.h="">
#include <arpa inet.h="">
#include <pthread.h>


#define MAX_CLIENTS 100
#define BUFFER_SZ 2048
#define name_len 32
// Global variables
volatile sig_atomic_t flag = 0;
volatile sig_atomic_t playflag = 0;
int sockfd = 0;
char name[name_len];

//overwriting the characters which have already been displayed by the terminal
void str_overwrite_stdout()
{
  printf("%s", ">");
  fflush(stdout);
  //sleep(1);//added
}


void str_trim_lf (char* arr, int length)
{
  int i;
  for (i = 0; i < length; i++)
  { // trim \n
    if (arr[i] == '\n')
    {
      arr[i] = '\0';
      break;
    }
  }
}


void catch_ctrl_c_and_exit(int sig)
{
    flag = 1;
}

void recv_msg_handler()
{
char message[BUFFER_SZ] = {};
  while (1)
  {
int receive = recv(sockfd, message, BUFFER_SZ, 0);
    if (receive > 0)
    {
      printf("%s", message);
        str_overwrite_stdout();
    } else if (receive == 0)
    {
break;
    } /*else {
// -1 }*/
bzero(message, sizeof(message));
  }
}


void send_msg_handler()
{
  char buffer[BUFFER_SZ] = {};
  char message[BUFFER_SZ + name_len+2] = {};

  while(1)
   {
    str_overwrite_stdout();
    fgets(buffer, BUFFER_SZ, stdin);
    str_trim_lf(buffer, BUFFER_SZ);

if(playflag ==0);
        {
/*////////////////////////////////////////////////////////////////////uselesssssss

        if(strcmp(buffer,"LIST") == 0)
        {
            int l = 0;
            for(int i = 0 ; i < clientCount ; i ++)
            {
                if(i != index)
                    l += snprintf(output + l,1024,"Client %d is at socket %d.\n",i +         1,Client[i].sockID);

            }
            send(clientSocket,output,1024,0);
            continue;

        }

*/



     if(strcmp(buffer,"ONLINE") == 0)
     {
 sprintf(message, "%s:%s\n", name, buffer);
      send(sockfd, message, strlen(message), 0);
    }


  else  if (strcmp(buffer, "exit") == 0)
    {
break;
    }
   
     /*else if (strcmp(buffer, "GAME") == 0)
        {
            sprintf(message, "%s:%s\n", name, "game begun \n game's rules:\n 1>one of the players gets to be a murdrer \n 2>allthe other players get to be the villegers \n 3>the villegers need idntify who is the murderer befor the the time ends\n");
            send(sockfd, message, strlen(message), 0);
            printf("game begun \n");
            printf("game's rules:\n 1>one of the players gets to be a murdrer \n 2>allthe other players get to be the villegers \n 3>the villegers need idntify who is the murderer befor the the time ends \n ");
        }
    */
   
    else {
      sprintf(message, "%s:%s\n", name, buffer);
      if(strcmp(buffer, "GAME")== 0 )
      {
      send(sockfd, buffer, strlen(buffer), 0);
      printf("game's rules:\n 1>one of the players gets to be a murdrer \n 2>allthe other players get to be the villegers \n 3>the villegers need idntify who is the murderer befor the the time ends \n ");
      }
     else send(sockfd, message, strlen(message), 0);
           }
     }
    bzero(buffer, BUFFER_SZ);
    bzero(message, BUFFER_SZ + name_len);
   
   }
  catch_ctrl_c_and_exit(2);
}




//main
int main(int argc, char **argv)
{

/*
  char massage[BUFFER_SZ];
    int numbytes;

*/
if(argc != 2)
{
printf("Usage: %s <port>\n", argv[0]);
return EXIT_FAILURE;
}

char *ip = "127.0.0.1";
int port = atoi(argv[1]);

signal(SIGINT, catch_ctrl_c_and_exit);

printf("Please enter your name: ");
  fgets(name, name_len, stdin);
  str_trim_lf(name, strlen(name));

if (strlen(name) > name_len-1 || strlen(name) < 2)
{
printf("Name must be less than 32 and more than 2 characters.\n");
return EXIT_FAILURE;
}

struct sockaddr_in server_addr;

//Socket settings
sockfd = socket(AF_INET, SOCK_STREAM, 0);//make socket  
  server_addr.sin_family = AF_INET;//ADDED - this reserts the socket parameters
  server_addr.sin_addr.s_addr = inet_addr(ip);
  server_addr.sin_port = htons(port);//"host to network,short" standart byte order synchrenize


// Connect to Server
  int err = connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));//try to connerct to server
  if (err == -1) //the error worning (could be done with if(... <0 then error without the int
  {
printf("ERROR: connect\n");
return EXIT_FAILURE;
}
// Send name
send(sockfd, name, 32, 0);

printf("elcome to mor-yael-sean (mys) chat  \n");
pthread_t send_msg_thread;
  if(pthread_create(&send_msg_thread, NULL, (void *) send_msg_handler, NULL) != 0)
  {
printf("ERROR: pthread\n");
    return EXIT_FAILURE;
}

pthread_t recv_msg_thread;
  if(pthread_create(&recv_msg_thread, NULL, (void *) recv_msg_handler, NULL) != 0)
  {
printf("ERROR: pthread\n");
return EXIT_FAILURE;
}

while (1)
{
if(flag)
{
printf("\nBye\n");
break;
    }
}

close(sockfd);

return EXIT_SUCCESS;
}


my server code:
C
<pre>#include <math.h> 
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>
#include <netinet in.h="">
#include <sys socket.h="">
#include <sys types.h="">
#include <arpa inet.h="">
#include <errno.h>
#include <signal.h>
#include <time.h> //time functions
#include <string.h>
#include <math.h>
//#include <dos.h>
#define MAX_CLIENTS 100
#define BUFFER_SZ 2048
#define name_len 18
static _Atomic unsigned int cli_count=0;
static int uid=10;

//Client structure
typedef struct{
struct sockaddr_in address;//adress
int sockfd;//socket field descriptor
int uid; //user id
char name[name_len];//user's name
int role; // (1. murderur) (2. villeger) (3.dead)
} client_t;

client_t *clients[MAX_CLIENTS];

pthread_mutex_t clients_mutex = PTHREAD_MUTEX_INITIALIZER;// this mutex we have to require when we are goind to transfer to send the massage between the clients
       
void delay(int number_of_seconds)
{
    // Converting time into milli_seconds
    int milli_seconds = 1000 * number_of_seconds;
 
    // Storing start time
    clock_t start_time = clock();
 
    // looping till required time is not achieved
    while (clock() < start_time + milli_seconds);
   
   
//delay(pow(i,2));//when we want to use it this is the code
}
   
   
   


void str_overwrite_stdout()
{
    printf("\r%s", " > ");
    fflush(stdout);
}

void str_trim_lf (char* arr, int length)
{
  int i;
  for (i = 0; i < length; i++)
{ // trim \n
    if (arr[i] == '\n')
{
  arr[i] = '\0';
      break;
    }
  }
}

//Add clients to queue
void queue_add(client_t *cl)
{
pthread_mutex_lock(&clients_mutex);

for(int i=0; i < MAX_CLIENTS; ++i)
{
if(!clients[i])
{
clients[i] = cl;
break;
}
}

pthread_mutex_unlock(&clients_mutex);
}

//Remove clients to queue
//that program know how to remove that client daddy, use the uniq id that all client have
void queue_remove(int uid)
{
pthread_mutex_lock(&clients_mutex);
for(int i=0; i < MAX_CLIENTS; ++i)
{
if(clients[i])
{
if(clients[i]->uid == uid)
{
clients[i] = NULL;
break;
}
}
}

pthread_mutex_unlock(&clients_mutex);
}

//how much clients are online right now
/*void counter_online()
{
cnt=0;
pthread_mutex_lock(&clients_mutex);
for(int i=0; i < MAX_CLIENTS; ++i)
{
if(clients[i])
cnt++;

}

pthread_mutex_unlock(&clients_mutex);
return cnt;
}

*/
// Send message to all clients except sender
void send_message(char *s, int uid)
{
pthread_mutex_lock(&clients_mutex);

for(int i=0; i<max_clients; ++i)
{
if(clients[i])
{
if(clients[i]-="">uid != uid)
{
if(write(clients[i]->sockfd, s, strlen(s)) < 0)
{
perror("ERROR: write to descriptor failed");
break;
}
}
}
}

pthread_mutex_unlock(&clients_mutex);
}

//Handle all communication with the client
void *handle_client(void *arg)
{
int counter;
char buff_out[BUFFER_SZ];
char name[32];
int leave_flag = 0;//indicate that whether the client is conected or not or there is an error
cli_count++;
client_t *cli = (client_t *)arg;

// Name
if(recv(cli->sockfd, name, name_len, 0) <= 0 || strlen(name) <  2 || strlen(name) >= 32-1)
{
printf("Didn't enter the name!\n");
leave_flag = 1;
} else{
strcpy(cli->name, name);
sprintf(buff_out, "%s has joined\n", cli->name);
printf("%s", buff_out);
send_message(buff_out, cli->uid);
              }

bzero(buff_out, BUFFER_SZ);

while(1)
{
if (leave_flag)
{
break;
          }
/* if(send(clients[1]->sockfd, "Wellcome\n", 9, 0) == -1)  
       perror("send");
       */
int receive = recv(cli->sockfd, buff_out, BUFFER_SZ, 0);
if (receive > 0)
{
if(strlen(buff_out) > 0)
{
//send_message(buff_out, cli->uid);
if (strcmp(buff_out, "GAME") == 0)
{
memcpy(buff_out,"game's rules:\n 1>one of the players gets to be a murdrer \n 2>allthe other players get to be the villegers \n 3>the villegers need idntify who is the murderer befor the the time ends \n ",strlen("game's rules:\n 1>one of the players gets to be a murdrer \n 2>allthe other players get to be the villegers \n 3>the villegers need idntify who is the murderer befor the the time ends \n ")+1);
send_message(buff_out, cli->uid);
//counter=counter_online();
char scount[5];
sprintf(scount,"%d",cli_count);
if(send(cli->sockfd, scount,3, 0) == -1)  
               perror("send");
}
else{
send_message(buff_out, cli->uid);
str_trim_lf(buff_out, strlen(buff_out));
//printf("%s -> %s\n", buff_out, cli->name);
printf("%s \n", buff_out);
   }
}
}/*else if (strcmp(buff_out,"ONLINE")==0)

queue_print();

*/
else if (receive == 0 || strcmp(buff_out, "exit") == 0)
{
sprintf(buff_out, "%s has left\n", cli->name);
printf("%s", buff_out);
send_message(buff_out, cli->uid);
leave_flag = 1;
       }
 /*      else if(receive == 0 || strcmp(buff_out, "GAME") == 0)
       
            {
            int cnt=0;
            for(int i=0; i < MAX_CLIENTS; ++i)
            {
           
                if(!clients[i])
               {
                    break;
                  }
           
           
            }
       
        {int count=0;
          for(int i=0; i < MAX_CLIENTS; ++i)
           {
               if (count==0)    
               {
               
               }
            clients[i] =(rand() % (2 - 1 + 1)) + 1;
           
            else
           clients[i]=1;
       }
       
        }
*/
  else {
printf("ERROR: -1\n");
leave_flag = 1;
}

bzero(buff_out, BUFFER_SZ);
}

//Delete client from queue and yield thread
close(cli->sockfd);
  queue_remove(cli->uid);
  free(cli);
  cli_count--;
  pthread_detach(pthread_self());

return NULL;
}



void print_client_addr(struct sockaddr_in addr)
{
    printf("%d.%d.%d.%d",
(addr.sin_addr.s_addr & 0xff),
        (addr.sin_addr.s_addr & 0xff00) >> 8,
        (addr.sin_addr.s_addr & 0xff0000) >> 16,
        (addr.sin_addr.s_addr & 0xff000000) >> 24);
}

int main(int argc, char **argv)
{
if(argc != 2)
{
printf("Usage: %s <port>\n", argv[0]);
return EXIT_FAILURE;
}

char *ip = "127.0.0.1";
int port = atoi(argv[1]);
//int port2 = atoi(argv[2]);
int option = 1;
int listenfd = 0, connfd = 0;
//int listenfd2 = 0, connfd2 = 0;
  struct sockaddr_in serv_addr;
  struct sockaddr_in cli_addr;
  pthread_t tid;

//Socket settings
listenfd = socket(AF_INET, SOCK_STREAM, 0);
serv_addr.sin_family = AF_INET;
  serv_addr.sin_addr.s_addr = inet_addr(ip);
  serv_addr.sin_port = htons(port);
  //serv_addr.sin_port = htons(port2);

//signals
signal(SIGPIPE, SIG_IGN);

if(setsockopt(listenfd, SOL_SOCKET,(SO_REUSEPORT | SO_REUSEADDR),(char*)&option,sizeof(option)) < 0)
{
perror("ERROR: setsockopt failed");
    return EXIT_FAILURE;
}

//Bind
  if(bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0)
{
           perror("ERROR: Socket binding failed");
           return EXIT_FAILURE;
  }

//Listen
  if (listen(listenfd, 10) < 0)
{
    perror("ERROR: Socket listening failed");
    return EXIT_FAILURE;
}
printf("this is our's chatroom\n");

while(1)
{
/*while(num)
    {
       cnt =pow(2,2)*1000;
       delay(cnt);//pow cnt =1000
       num --;
         printf("shss");
       
    }
    */




//accept the conect with client
socklen_t clilen = sizeof(cli_addr);
connfd = accept(listenfd, (struct sockaddr*)&cli_addr, &clilen);

//Check if max clients is reached
if((cli_count + 1) == MAX_CLIENTS)
{
printf("Max clients reached therfore Rejected: ");
print_client_addr(cli_addr);
printf(":%d\n", cli_addr.sin_port);//print the client addres that rejected
close(connfd);
continue;
}




//Client settings
client_t *cli = (client_t *)malloc(sizeof(client_t));
cli->address = cli_addr;
cli->sockfd = connfd;
cli->uid = uid++;

//Add client to the queue and fork thread
queue_add(cli);
pthread_create(&tid, NULL, &handle_client, (void*)cli);

//Reduce CPU usage
sleep(1);
}

return EXIT_SUCCESS;
}
Posted
Updated 19-Jul-22 20:03pm
v2

1 solution

Quote:
And how exactly do I run the second server in Linux.
Like the first one, using a different port. That's all (folks).
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900