Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

Change this client server distributed chat program in C to be able to pass strings back and forth in a chat rather than a single

Change this client server distributed chat program in C to be able to pass strings back and forth in a chat rather than a single character to pass and make it so that the server stores each username.

After connecting, all messages sent by any user should be broadcast to all other user currently connected. In addition, the server should inform all clients whenever a new user logs in. For example, suppose that "Anne", "Beth", and "Claire" are currently logged in. If Anne enters "Hi Beth", then the server should broadcast "Anne: Hi Beth" to all other users, namely Beth and Claire. If another user, say "Dan", joins the chat session, then the server should inform Anne, Beth, and Claire by broadcasting the message "Dan has joined the chat". The first user to login should receive the message "You are the first user to join the chat"

/*Server.c*/ #include #include #include #include #include #include #include #include #include #include "inet.h"

#define BUF_SIZE 100 #define DEBUG 1

void * do_something(void *); /*New thread's code*/

int serverSocket; pthread_t *threads; unsigned int *threads_ids; int numClients = 0;

int main(int argc, char **argv) { int num_threads = 5; int i; int ret_val; pthread_attr_t attr; struct sockaddr_in server; char usernames[20][BUF_SIZE];

/*Create communication endpoint*/ if((serverSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("Error creating socket "); return(1); }

printf("Socket created... "); /*Bind socket to local address*/ memset((char *)&server, 0, sizeof(server)); server.sin_family = AF_INET; server.sin_addr.s_addr = htonl(INADDR_ANY); server.sin_port = htons(SERV_TCP_PORT);

if(bind(serverSocket, (struct sockaddr *)&server, sizeof(server)) < 0) { perror("Error binding "); return(1); } printf("Binding done... "); listen(serverSocket, 5);

/*Create worker threads*/ threads = (pthread_t *) malloc((num_threads + 1) * sizeof(pthread_t)); threads_ids = (unsigned int *)malloc((num_threads + 1) *sizeof(unsigned int));

/*Intialize and set thread detached attribute*/ pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); threads[0] = pthread_self(); /*Parent thread*/

for(i = 1; i <= num_threads; i++) { ret_val = pthread_create(&threads[i], &attr, do_something, NULL); if(ret_val < 0) { printf("ERROR: return code from pthreadf_create() is %d ", ret_val); exit(-1); } }

/*Free attribute and wait for the worker threads to exit*/ pthread_attr_destroy(&attr);

for(i = 1; i <= num_threads; i++) { pthread_join(threads[i], NULL); #if DEBUG printf(" Thread %u hoined with parent. ", (int)threads[i]); #endif } free(threads); #if DEBUG printf(" Parent is exiting, sorry clients... "); #endif exit(0); }

void * do_something(void * arg) { int newServerSocket, clilen, childpid; struct sockaddr_in client, server; char sendBuffer[BUF_SIZE]; char rcvBuffer; int num_threads = 5; int i; struct tm *timeptr; time_t clock; unsigned tid; /*Thread id*/ int nread; tid = pthread_self(); /*who am i*/

for(i = 1; i <= 2; i++) { /*Accept a new communication request*/ clilen = sizeof(client); newServerSocket = accept(serverSocket, (struct sockaddr *) &client, &clilen); if(newServerSocket < 0) { perror("Server: accept error"); exit(1); } /*Rread the request from the client*/ nread = read(newServerSocket, &rcvBuffer, sizeof(char)); #if DEBUG printf("Thread %u read request %c ", tid, rcvBuffer); #endif /*Genereate an appropriate reply*/ while(nread > 0) { clock = time(0); timeptr = localtime(&clock);

switch(rcvBuffer) { case '1': strftime(sendBuffer, BUF_SIZE, "%A, %d, %Y", timeptr); break; case '2': strftime(sendBuffer, BUF_SIZE, "%T", timeptr); break; case '3': strftime(sendBuffer, BUF_SIZE, "%A, %d, %Y - %T", timeptr); break; default: strcpy(sendBuffer, "Invalid request "); break; } write(newServerSocket, sendBuffer, BUF_SIZE); nread = read(newServerSocket, &rcvBuffer, sizeof(char)); } close(newServerSocket); } pthread_exit(0);

}

/*Client.c*/ #include #include #include #include #include #include #include #include "inet.h"

#define BUF_SIZE 100

int get_response(void); int readn(int, char *, int);

int clientSocket, response, nread; int first = 0; struct sockaddr_in server; char username[30]; char rcvBuffer[BUF_SIZE]; char sendBuffer[BUF_SIZE]; int flag = 0; socklen_t addr_size;

int main(int argc, char ** argv) { int response;

/*Set up address of server*/ memset((char *)&server, 0, sizeof(server)); server.sin_family = AF_INET; server.sin_addr.s_addr = inet_addr(SERV_HOST_ADDR); server.sin_port = htons(SERV_TCP_PORT);

addr_size = sizeof(server);

while((response = get_response()) != 4) { /*Create socket*/ if((clientSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("Error creating socket "); return(1); }

/*Connect to the server*/ if(connect(clientSocket, (struct sockaddr *) &server, sizeof(server)) < 0) { perror("Client: can't connect to the server "); return(1); }

sprintf(sendBuffer, "%d", response);

/*Send the user's request to the server*/ /*write(clientSocket, sendBuffer, sizeof(char *));*/ write(clientSocket, sendBuffer, sizeof(char)); /*Read servers ireply*/ nread = readn(clientSocket, sendBuffer, BUF_SIZE); if(nread > 0)

{ printf(" %s ", sendBuffer); } else{ printf("Nothing to read "); } close(clientSocket);

}

return 0; }

/*Display menu and retrieve user's response*/ int get_response(void) { int choice;

printf("=========================================== "); printf(" Menu: "); printf("------------------------------------------- "); printf(" 1. Date "); printf(" 2. Time "); printf(" 3. Both "); printf(" 4. Quit "); printf("------------------------------------------- "); printf(" Choice (1-4):"); scanf("%d",&choice); printf("=========================================== "); return(choice); }

/*Read up to "n" bytes from a descriptor. Use place of read() when fd is a stream socket*/ int readn(fd, ptr, nbytes) register int fd; register char *ptr; register int nbytes; { int nleft, nread; nleft = nbytes; while(nleft > 0) { nread= read(fd, ptr, nleft); if(nread < 0) return(nread); /*Error: return < 0*/ else if(nread == 0) break; /*EOF*/ nleft -= nread; ptr += nread; } return(nbytes - nleft); /*Return >= 0*/ }

/*inet.h*/

/* * Defintions for TCP and UDP client/server programs */

#include #include #include #include #include #include #include #include #include #define SERV_TCP_PORT 4678 #define SERV_HOST_ADDR "129.130.10.43" /* Change this to be your host addr */

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Fundamentals Of Database Systems

Authors: Sham Navathe,Ramez Elmasri

5th Edition

B01FGJTE0Q, 978-0805317558

More Books

Students also viewed these Databases questions