Добавление команды истории в многоклиентную серверную программу - PullRequest
0 голосов
/ 15 ноября 2018

У меня есть эта клиентская и серверная программа.Я пытаюсь добавить команду истории, где она отображает последние 10 команд при вводе «истории» в командной строке, но у меня возникают проблемы с ней, когда она вообще не отображается, но я не знаю, почемуэто не сработает.После того, как я наберу «history», он ничего не отобразит, и я не могу вводить какие-либо команды, после чего мне приходится перезапускать код, чтобы иметь возможность вводить команды Unix. Эта программа работает, отправляя команды Unix, такие как «ls»."или" date "и он отправит информацию с сервера обратно клиенту.Это может быть потому, что мой код немного глючит, но он все равно должен работать.Кто-нибудь может указать мне правильное направление?

Клиент:

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

#define BUFFSIZE 2048

char history[10][50];
int historyCounter = 0;

char *encryptedMessage(char command[]){
    int i = 0;

    while (command[i] != '\0'){
        command[i] += 5;
        i += 1;
    }

    return command;
}



int main(int argc, char *argv[]){
    /*Created variables for socket, server address, arguement size, and a buffer*/
    int clientSocket, ret, portnum;
    struct sockaddr_in serverAddr;
    int received = 0;
    unsigned int echolen;
    char buffer[BUFFSIZE];

    /*If there is less than 3 arguments, print out a statement explaining to execute program
    along witjh server ip and port*/
    if(argc < 3){
        fprintf(stderr,"usage %s <server-ip-addr> <server-port>\n", argv[0]);
        exit(0);
    }
    /*Convert port number from the commandline using atoi*/
    portnum = atoi(argv[2]);

    /*Create socket, and check if there is an error in the connection*/
    clientSocket = socket(AF_INET, SOCK_STREAM, 0);
    if(clientSocket < 0){
        printf("Error in connection.\n");
        exit(1);
    }
    printf("Client Socket is created.\n");
    /*Memset server address*/
    memset(&serverAddr, '\0', sizeof(serverAddr));
    // memset(&buffer, '\0', sizeof(buffer));
    // serverAddr.sin_family = AF_INET;
    // serverAddr.sin_port = htons(PORT);
    // serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");

    // bzero((char *) &serverAddr, sizeof(serverAddr));

    /*Take ip address from commandline and set it into serverAddr*/
    serverAddr.sin_family = AF_INET;
    if(!inet_aton(argv[1], &serverAddr.sin_addr)){
        fprintf(stderr, "Error invalid server IP address\n");
        exit(1);
    }
    /*Take the port number and set it in the sin_port for connection*/
    serverAddr.sin_port = htons(portnum);
    /*Connect the client to the server, if less than 0, then there is an error in the connection*/
    ret = connect(clientSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
    if(ret < 0){
        printf("Error in connection.\n");
        exit(1);
    }
    printf("Connected to server.\n");
    /*Initialize argument buffer*/
    char s[100];
    /*In the while loop we take the arguments after we connect and put them in stdin, we insert \0 at the
    end of s array*/
    while(1){
        int _switch = 0;
        fgets(s, 100, stdin);
        historyCounter++;
        //s[strlen(s)-1]='\0';
        echolen = strlen(s);
        if(historyCounter < 10){
            for(int i = 0; i < historyCounter; i++){
                strcpy(history[i+1], history[i]);
            }
        }
        strcpy(history[0], s);

        /*  send() from client, if it doesn't equal echolen then show it failed */
        if(strcmp(s,"history") == 0){
            _switch = 1;
            int a = 0;
            int b = 0;

            for (int a = 0; a < historyCounter; a++){
                printf("%d", historyCounter);
                while(history[a][b] != '\0'){
                    printf("%c", history[a][b]);
                    b++;
                }
                b = 0;
                printf("\n");
            }
            printf("\n");

        }


        if(_switch == 0){
            if (send(clientSocket, s, echolen, 0) != echolen)
        {
            printf("Failed");
        }

        if(strcmp(s,"quit") == 0) //check if exit is typed
            exit(0);
        fprintf(stdout, "Message from server: ");
        //fprintf(stdin, "%s\n", s);
        while (received < echolen)
        {
            ssize_t bytes = 0;
            /* recv() from server, the bytes we receive are from the clientSocket */
            if ((bytes = recv(clientSocket, buffer, echolen, 0)) < 1)
            {
                printf("Failed to get Information");
            }
            received += bytes;
            buffer[bytes] = '\0';
            /*WE receive the information and print in stdout what's in the buffer*/
            fprintf(stdout, buffer);
        }
        ssize_t bytes = 0;
        /*Place /0 at end of the buffer*/
        do {
            buffer[bytes] = '\0';
            printf("%s\n", buffer);
        } while((bytes = recv(clientSocket, buffer, BUFFSIZE-1, 0))>=BUFFSIZE-1);
        buffer[bytes] = '\0';
        printf("%s\n", buffer);
        printf("\n");
        }

        /*Above is essentially printing out the information within the buffer from the recv()*/

    }
}

Сервер:

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

#define PORT 4444
#define BUFFSIZE 2048
#define MAX 2048
/*Full Credit implementing command argument functions: https://stackoverflow.com/questions/52796610/multiclient-and-server-commandline-argument-issues*/
/*setup() function take the input bugger and the arguments and tokenizes the arguments into the inputBuffer*/
void setup(char inputBuffer[], char *args[], int *background){
    const char s[4] = " \t\n";
    char *token;
    token = strtok(inputBuffer, s);
    int i = 0;
    while(token != NULL){
        args[i] = token;
        i++;
        token = strtok(NULL, s);
    }
    args[i] = NULL;
}
/*HandleClient() function take the socket, grabs the data from the client from the buffer*/
void HandleClient(int sock){
    char buffer[BUFFSIZE];
    int received = -1;
    char data[MAX];
    memset(data, 0, MAX);
    /*recv grabs info from the buffer*/
    while(1){
        data[0] = '\0';
        if((received = recv(sock, buffer, BUFFSIZE, 0)) < 0){
            printf("Error");
        }

        buffer[received] = '\0';

        strcat(data, buffer);
        if(strcmp(data, "exit") == 0){
            exit(0);
        }
        /*Put data into an arg array and pipe*/
        puts(data);
        char *args[100];
        setup(data, args, 0);
        int pipefd[2], length;

        if(pipe(pipefd)){
            printf("failed to create pipe");
        }
        /*Fork a child*/
        pid_t pid = fork();
        char path[MAX];

        if(pid==0)
        {
            close(pipefd[0]); // close the readonly side of the pipe
            //close(1); // close the original stdout
            dup2(pipefd[1],1); // duplicate pipfd[1] to stdout
            dup2(pipefd[1], fileno(stderr));
            //close(pipefd[0]); // close the readonly side of the pipe
            close(pipefd[1]); // close the original write side of the pipe
            printf("before execvp");
            execvp(args[0],args); // finally execute the command
            // exit(0);
        }
        else
            if(pid>0)
            {
                close(pipefd[1]);
                memset(path,'\0',MAX);
                while(length=read(pipefd[0],path,MAX-1)){
                    //printf("Data read so far %s\n", path);
                    if(send(sock,path,strlen(path),0) != strlen(path) ){
                        printf("Failed");
                    }
                    fflush(NULL);
                    //printf("Data sent so far %s\n", path);
                memset(path,0,MAX);
                }
                close(pipefd[0]);

                //exit(1); removed so server will not terminate
            }
            else
            {
                printf("Error !\n");
                exit(0);//
            }

    }
}

char *decryptedMessage(char command[]){
    int i = 0;

    while (command[i] != '\0'){
        command[i] -= 5;
        i += 1;
    }

    return command;
}


int main(){
    /*Create all the sock, server address, and pid variables*/
    int sockfd, ret;
    struct sockaddr_in serverAddr;

    int newSocket;
    struct sockaddr_in newAddr;

    socklen_t addr_size;

    char buffer[1024];
    pid_t childpid;
    /*Create a socket*/
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd < 0){
        printf("Error in connection.\n");
        exit(1);
    }
    printf("Server Socket is created.\n");
    /*Memset the serverAddr, and put the ip and port number into the serverAddr structure*/
    memset(&serverAddr, '\0', sizeof(serverAddr));
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(PORT);
    serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");

    //printf("IP address is: %s\n", inet_ntoa(client_addr.sin_addr));
    //printf("port is: %d\n", (int) ntohs(client_addr.sin_port));

    /*Bind to the port*/
    ret = bind(sockfd, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
    if(ret < 0){
        printf("Error in binding");
        exit(1);
    }
    printf("Bind to port %d\n", 4444);

    if(listen(sockfd, 10) == 0){
        printf("Listening....\n"); //Listening to accept connections
    }else{
        printf("Error in binding.\n");
    }

    while(1){
        newSocket = accept(sockfd, (struct sockaddr*) &newAddr, &addr_size); //accept the socket and server address
        if(newSocket < 0){
            exit(1);
        }
        printf("Connection accepted from %s:%d\n", inet_ntoa(newAddr.sin_addr), ntohs(newAddr.sin_port));

        //Take the buffer from the server and send it back to the client through the socket
        if((childpid = fork()) == 0){
            close(sockfd);

            while(1){
                recv(newSocket, buffer, 1024, 0); //recv() get the buffer and set the size 1024
                if(strcmp(buffer, "quit") == 0){
                    printf("Disconnected from %s:%d\n", inet_ntoa(newAddr.sin_addr), ntohs(newAddr.sin_port));
                    break;
                }else{
                    printf("Client: %s\n", buffer);
                    send(newSocket, buffer, strlen(buffer), 0); //sending info back to the client
                    bzero(buffer, sizeof(buffer));
                }
                HandleClient(newSocket);
            }
        }
    }


    close(newSocket);
    return 0;
}

1 Ответ

0 голосов
/ 15 ноября 2018

fgets () читает до новой строки, но также копирует эту новую строку в конце входного буфера.В strcmp () для команды history может произойти сбой.Пожалуйста, проверьте man страницу fgets ().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...