Question

In: Computer Science

A limitation of the chat server is that it can handle only one client because it...

A limitation of the chat server is that it can handle only one client because it is a single threaded application. Using the pThread library, modify the chat server so that it can handle multiple clients simultaneously, i.e., by creating a new thread whenever a client is connected so that the client is handled individually with a new thread, and at the same time, by having the main thread (i.e., the thread that runs the main function) of the chat server continue to wait for an incoming connection from a client.

The current implementation of the chat server allows the server to exchange messages with a client individually. Modify the server code so that when the server sends a message, that message is sent to all connected clients. We will test your program with three clients.

Create another thread for the chat server that broadcasts current system time to all connected clients every 5 seconds. For example, all clients should receive a message containing current system time periodically and print it out.

Server.c

#include <stdio.h>

#include <netdb.h>

#include <netinet/in.h>

#include <stdlib.h>

#include <string.h>

#include <sys/socket.h>

#include <sys/types.h>

#define MAX 80

#define PORT 8080

#define SA struct sockaddr

#define MAX 80

#define PORT 8080

#define SA struct sockaddr

  

// Function designed for chat between client and server.

void func(int sockfd)

{

    char buff[MAX];

    int n;

    // infinite loop for chat

    for (;;) {

        bzero(buff, MAX);

  

        // read the message from client and copy it in buffer

        read(sockfd, buff, sizeof(buff));

        // print buffer which contains the client contents

        printf("From client: %s\t To client : ", buff);

        bzero(buff, MAX);

        n = 0;

        // copy server message in the buffer

        while ((buff[n++] = getchar()) != '\n')

            ;

  

        // and send that buffer to client

        write(sockfd, buff, sizeof(buff));

  

        // if msg contains "Exit" then server exit and chat ended.

        if (strncmp("exit", buff, 4) == 0) {

            printf("Server Exit...\n");

            break;

        }

    }

}

  

// Driver function

int main()

{

    int sockfd, connfd, len;

    struct sockaddr_in servaddr, cli;

  

    // socket create and verification

    sockfd = socket(AF_INET, SOCK_STREAM, 0);

    if (sockfd == -1) {

        printf("socket creation failed...\n");

        exit(0);

    }

    else

        printf("Socket successfully created..\n");

    bzero(&servaddr, sizeof(servaddr));

  

    // assign IP, PORT

    servaddr.sin_family = AF_INET;

    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

    servaddr.sin_port = htons(PORT);

  

    // Binding newly created socket to given IP and verification

    if ((bind(sockfd, (SA*)&servaddr, sizeof(servaddr))) != 0) {

        printf("socket bind failed...\n");

        exit(0);

    }

    else

        printf("Socket successfully binded..\n");

  

    // Now server is ready to listen and verification

    if ((listen(sockfd, 5)) != 0) {

        printf("Listen failed...\n");

        exit(0);

    }

    else

        printf("Server listening..\n");

    len = sizeof(cli);

  

    // Accept the data packet from client and verification

    connfd = accept(sockfd, (SA*)&cli, &len);

    if (connfd < 0) {

        printf("server acccept failed...\n");

        exit(0);

    }

    else

        printf("server acccept the client...\n");

  

    // Function for chatting between client and server

    func(connfd);

  

    // After chatting close the socket

    close(sockfd);

}

Client.c

#include <netdb.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <sys/socket.h>

#define MAX 80

#define PORT 8080

#define SA struct sockaddr

void func(int sockfd)

{

    char buff[MAX];

    int n;

    for (;;) {

        bzero(buff, sizeof(buff));

        printf("Enter the string : ");

        n = 0;

        while ((buff[n++] = getchar()) != '\n')

            ;

        write(sockfd, buff, sizeof(buff));

        bzero(buff, sizeof(buff));

        read(sockfd, buff, sizeof(buff));

        printf("From Server : %s", buff);

        if ((strncmp(buff, "exit", 4)) == 0) {

            printf("Client Exit...\n");

            break;

        }

    }

}

  

int main()

{

    int sockfd, connfd;

    struct sockaddr_in servaddr, cli;

  

    // socket create and varification

    sockfd = socket(AF_INET, SOCK_STREAM, 0);

    if (sockfd == -1) {

        printf("socket creation failed...\n");

        exit(0);

    }

    else

        printf("Socket successfully created..\n");

    bzero(&servaddr, sizeof(servaddr));

  

    // assign IP, PORT

    servaddr.sin_family = AF_INET;

    servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");

    servaddr.sin_port = htons(PORT);

  

    // connect the client socket to server socket

    if (connect(sockfd, (SA*)&servaddr, sizeof(servaddr)) != 0) {

        printf("connection with the server failed...\n");

        exit(0);

    }

    else

        printf("connected to the server..\n");

  

    // function for chat

    func(sockfd);

  

    // close the socket

    close(sockfd);

}

Solutions

Expert Solution

Client.c

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

void * doRecieving(void * sockID){

        int clientSocket = *((int *) sockID);

        while(1){

                char data[1024];
                int read = recv(clientSocket,data,1024,0);
                data[read] = '\0';
                printf("%s\n",data);

        }

}

int main(){

        int clientSocket = socket(PF_INET, SOCK_STREAM, 0);

        struct sockaddr_in serverAddr;

        serverAddr.sin_family = AF_INET;
        serverAddr.sin_port = htons(8080);
        serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);

        if(connect(clientSocket, (struct sockaddr*) &serverAddr, sizeof(serverAddr)) == -1) return 0;

        printf("Connection established ............\n");

        pthread_t thread;
        pthread_create(&thread, NULL, doRecieving, (void *) &clientSocket );

        while(1){

                char input[1024];
                scanf("%s",input);

                if(strcmp(input,"LIST") == 0){

                        send(clientSocket,input,1024,0);

                }
                if(strcmp(input,"SEND") == 0){

                        send(clientSocket,input,1024,0);
                        
                        scanf("%s",input);
                        send(clientSocket,input,1024,0);
                        
                        scanf("%[^\n]s",input);
                        send(clientSocket,input,1024,0);

                }

        }


}

Server.c

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

int clientCount = 0;

static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

struct client{

        int index;
        int sockID;
        struct sockaddr_in clientAddr;
        int len;

};

struct client Client[1024];
pthread_t thread[1024];

void * doNetworking(void * ClientDetail){

        struct client* clientDetail = (struct client*) ClientDetail;
        int index = clientDetail -> index;
        int clientSocket = clientDetail -> sockID;

        printf("Client %d connected.\n",index + 1);

        while(1){

                char data[1024];
                int read = recv(clientSocket,data,1024,0);
                data[read] = '\0';

                char output[1024];

                if(strcmp(data,"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(data,"SEND") == 0){

                        read = recv(clientSocket,data,1024,0);
                        data[read] = '\0';

                        int id = atoi(data) - 1;

                        read = recv(clientSocket,data,1024,0);
                        data[read] = '\0';

                        send(Client[id].sockID,data,1024,0);                    

                }

        }

        return NULL;

}

int main(){

        int serverSocket = socket(PF_INET, SOCK_STREAM, 0);

        struct sockaddr_in serverAddr;

        serverAddr.sin_family = AF_INET;
        serverAddr.sin_port = htons(8080);
        serverAddr.sin_addr.s_addr = htons(INADDR_ANY);


        if(bind(serverSocket,(struct sockaddr *) &serverAddr , sizeof(serverAddr)) == -1) return 0;

        if(listen(serverSocket,1024) == -1) return 0;

        printf("Server started listenting on port 8080 ...........\n");

        while(1){

                Client[clientCount].sockID = accept(serverSocket, (struct sockaddr*) &Client[clientCount].clientAddr, &Client[clientCount].len);
                Client[clientCount].index = clientCount;

                pthread_create(&thread[clientCount], NULL, doNetworking, (void *) &Client[clientCount]);

                clientCount ++;
 
        }

        for(int i = 0 ; i < clientCount ; i ++)
                pthread_join(thread[i],NULL);

}

The client first needs to connect with the server and can then issue two commands -
1. GET - This command fetches the list of client's that are currently connected to server.
2. SEND (client number) (message) - SEND followed by client number which can be be used to send the message to particular to that particular client number. (please issue the complete send command in one go).
  
To run these program first run ChatServer.c and then run multiple instatnces of ChatServer.c .

OR

This is the server program,put your client code on different machine and try to connect from multiple client.

#include<stdio.h>
#include<string.h>    //strlen
#include<stdlib.h>    //strlen
#include<sys/socket.h>
#include<arpa/inet.h> //inet_addr
#include<unistd.h>    //write
#include<pthread.h> //for threading , link with lpthread
#define MAX 80

#define PORT 6543
#define SA struct sockaddr
// Function designed for chat between client and server.
void join(  pthread_t *thread_id)
{
    if(!pthread_join( *thread_id , NULL))
    printf("thread %ld complted\n",*thread_id);
    pthread_exit(0);//to exit the current thread

}

void func(int *sockfd)
{
    char buff[MAX];
    int n;
    // infinite loop for chat
    for (;;) {
        bzero(buff, MAX);
        // read the message from client and copy it in buffer
        read(*sockfd, buff, sizeof(buff));
        // print buffer which contains the client contents
        printf("From client: %s\t To client : ", buff);
        bzero(buff, MAX);
        n = 0;
        // copy server message in the buffer
        while ((buff[n++] = getchar()) != '\n');
        // and send that buffer to client
        write(*sockfd, buff, sizeof(buff));
        // if msg contains "Exit" then server exit and chat ended.
        if (strncmp("exit", buff, 4) == 0) {
            printf("Server Exit...\n");
            break;
        }

    }
}

// Driver function

int main()
{
    int sockfd, connfd, len;
    struct sockaddr_in servaddr, cli;
    pthread_t thread_id,jointhread_id;
    // socket create and verification
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == -1) {
        printf("socket creation failed...\n");
        exit(0);
    }
    else
        printf("Socket successfully created..\n");
    bzero(&servaddr, sizeof(servaddr));
    // assign IP, PORT
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = INADDR_ANY;
    servaddr.sin_port = htons(PORT);
    // Binding newly created socket to given IP and verification
    if ((bind(sockfd, (SA*)&servaddr, sizeof(servaddr))) != 0) {
        printf("socket bind failed...\n");
        exit(0);
    }
    else
        printf("Socket successfully binded..\n");
    // Now server is ready to listen and verification
    if ((listen(sockfd, 5)) != 0) {
        printf("Listen failed...\n");
        exit(0);
    }
    else
        printf("Server listening..\n");
    len = sizeof(cli);
    // Accept the data packet from client and verification
    while(connfd = accept(sockfd, (SA*)&cli, &len))
    {
    if (connfd < 0) {
        printf("server acccept failed...\n");
        exit(0);
    }
    else
        printf("server acccept the client..%d.\n",connfd);
    if( pthread_create( &thread_id , NULL ,  func , (void*) &connfd) < 0)
        {
            perror("could not create thread");
            return 1;
        }
        
    if( pthread_create( &jointhread_id , NULL ,  join , (void*) &thread_id) < 0)
        {
            perror("could not create thread");
            return 1;
        }
       
    }
    
    // After chatting close the socket
    close(sockfd);
}

first thread is created to handle the client and second thread is created to wait for client thread termination and then exit itself.


Related Solutions

In Simple Chat, if the server shuts down while a client is connected, the client does...
In Simple Chat, if the server shuts down while a client is connected, the client does not respond, and continues to wait for messages. Modify the client so that it responds to the shutdown of server by printing a message saying the server has shut down, and quitting. (look at the methods called connectionClosed and connectionException). //ChatClient.java // This file contains material supporting section 3.7 of the textbook: // "Object Oriented Software Engineering" and is issued under the open-source //...
what will be the code in C programming for the client and server chat application for...
what will be the code in C programming for the client and server chat application for the below issue :- write the C Programming code that able client have a unique ID to be known by the server
In the provided client and server code, the server can serve to single client at a...
In the provided client and server code, the server can serve to single client at a time. You have to change server.java code so that it can connect and serve multiple clients at the same time. Use multithreading. =============================================================================== import java.io.*; import java.net.*; public class Client { public static void main(String[] args) throws IOException { String serverHostname = new String ("127.0.0.1"); if (args.length > 0) { //pass the hsotname through cmd argument serverHostname = args[0]; } System.out.println ("Attemping to connect...
There are many factors that can influence such decision for cloud server and client server. security,...
There are many factors that can influence such decision for cloud server and client server. security, cost, training and more. which would you choose and why ? there are many factors that influenced the decision on a cloud server or client server such as cost, security, training and more. which one would you choose, cost, security,training etc. and why ? cancel that answer
Greetings, Consider a client server model.The server sends the message 'I am the server' to client....
Greetings, Consider a client server model.The server sends the message 'I am the server' to client. Describe and compare in details how the client and server exchange these messages using internet domain in the following two modes. a) connection-oriented modes b) connectionless-oriented modes
The client connects to the server. The server accepts the connection. The client sends a line...
The client connects to the server. The server accepts the connection. The client sends a line of text containing only SHAKESPEARE_COUNTS. The server sends back a sequence of integers. The number of integers in that list specifies the number of words in each insult; the numbers themselves specify how many possible words there are in each position. So, for example, if you received the output 15 20 30, it would indicate that insults are three words long, with 15 possible...
in Java - implement ftp-server and ftp-client. ftp-server Logging into ftp-server from ftp-client The ftp-server is...
in Java - implement ftp-server and ftp-client. ftp-server Logging into ftp-server from ftp-client The ftp-server is an interactive, command-line program that creates a server socket, and waits for connections. Once connected, the ftp-client can send and receive files with ftp-server until ftp-client logs out. Sending and receiving files The commands sent from the ftp-client to the ftp-server must recognize and handle are these: rename- the ftp-server responds to this command by renaming the named file in its current directory to...
Antibodies are suitable for diagnostic tests, because Select one: a. they can be used only for...
Antibodies are suitable for diagnostic tests, because Select one: a. they can be used only for humans. b. they can be readily purified. c. they are found in very small quantities. d. they bind very specifically to antigens with very high affinity. e. they are found everywhere.
Recall that even if the server only stores f(p), client has to send p in clear...
Recall that even if the server only stores f(p), client has to send p in clear to authenticate to the server. If the adversary is watching, it learns p. Normally you have to use HTTPS to solve this problem. Alice has another idea. Instead of client sending p, client will instead only send f(p) to the server to authenticate. Then the adversary never learns p even if it can watch the whole communication. Is this a good idea?
The following three projects are available but because of resource limitations, only one can be done....
The following three projects are available but because of resource limitations, only one can be done. The Do Nothing option is also available and the company MARR is 15%. F0 F1 F2 F3 F4 F5 A -$10,000 $5,000 $2,000 $2,500 $3,000 $3,100 B -$7,000 $2,000 $2,500 $3,000 $2,000 $1,000 C -$6,000 $2,000 $2,000 $2,500 $2,750 $3,000 a) Which project should be selected using ROR incremental analysis? b) Which project should be selected using present worth incremental analysis?
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT