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:
#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
volatile sig_atomic_t flag = 0;
volatile sig_atomic_t playflag = 0;
int sockfd = 0;
char name[name_len];
void str_overwrite_stdout()
{
printf("%s", ">");
fflush(stdout);
}
void str_trim_lf (char* arr, int length)
{
int i;
for (i = 0; i < length; i++)
{ 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;
}
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);
{
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 {
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);
}
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]);
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;
sockfd = socket(AF_INET, SOCK_STREAM, 0); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = inet_addr(ip);
server_addr.sin_port = htons(port);
int err = connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)); if (err == -1) {
printf("ERROR: connect\n");
return EXIT_FAILURE;
}
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:
<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>
#define MAX_CLIENTS 100
#define BUFFER_SZ 2048
#define name_len 18
static _Atomic unsigned int cli_count=0;
static int uid=10;
typedef struct{
struct sockaddr_in address;int sockfd;int uid; char name[name_len];int role; } client_t;
client_t *clients[MAX_CLIENTS];
pthread_mutex_t clients_mutex = PTHREAD_MUTEX_INITIALIZER;
void delay(int number_of_seconds)
{
int milli_seconds = 1000 * number_of_seconds;
clock_t start_time = clock();
while (clock() < start_time + milli_seconds);
}
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++)
{ if (arr[i] == '\n')
{
arr[i] = '\0';
break;
}
}
}
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);
}
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);
}
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);
}
void *handle_client(void *arg)
{
int counter;
char buff_out[BUFFER_SZ];
char name[32];
int leave_flag = 0;cli_count++;
client_t *cli = (client_t *)arg;
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;
}
int receive = recv(cli->sockfd, buff_out, BUFFER_SZ, 0);
if (receive > 0)
{
if(strlen(buff_out) > 0)
{
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);
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 \n", buff_out);
}
}
}
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 {
printf("ERROR: -1\n");
leave_flag = 1;
}
bzero(buff_out, BUFFER_SZ);
}
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 option = 1;
int listenfd = 0, connfd = 0;
struct sockaddr_in serv_addr;
struct sockaddr_in cli_addr;
pthread_t tid;
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);
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;
}
if(bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0)
{
perror("ERROR: Socket binding failed");
return EXIT_FAILURE;
}
if (listen(listenfd, 10) < 0)
{
perror("ERROR: Socket listening failed");
return EXIT_FAILURE;
}
printf("this is our's chatroom\n");
while(1)
{
socklen_t clilen = sizeof(cli_addr);
connfd = accept(listenfd, (struct sockaddr*)&cli_addr, &clilen);
if((cli_count + 1) == MAX_CLIENTS)
{
printf("Max clients reached therfore Rejected: ");
print_client_addr(cli_addr);
printf(":%d\n", cli_addr.sin_port);close(connfd);
continue;
}
client_t *cli = (client_t *)malloc(sizeof(client_t));
cli->address = cli_addr;
cli->sockfd = connfd;
cli->uid = uid++;
queue_add(cli);
pthread_create(&tid, NULL, &handle_client, (void*)cli);
sleep(1);
}
return EXIT_SUCCESS;
}