退出()调用时出现段错误

时间:2019-12-03 06:32:35

标签: c server client one-time-password

我正在编写一个用于模拟服务器和客户端一次密码的程序。客户端发送明文或密文文件和密钥文件。服务器侦听一个客户端进程,该进程发送一个缓冲区,该缓冲区包含一个方法(加密(otp_enc)或解密(otp_dec))和两个文件名(input_file_name和key_file_name),程序打开文件并将纯文本或密文写入到文件中。缓冲并发送回客户端,以打印输出。

用户在命令行上调用:

otp_dec_d [port_number] & (server runs in background) 
otp_dec plaintext_file_name key_file_name [port_number] 

程序运行完美,除非我试图将退出状态设置为2(如果方法与端口号不匹配),就像这样...

otp_dec_d 56780 &
otp_enc_d 56781 &
otp_enc plaintext_file_name key_file_name 56780

而且我遇到了段错误。知道为什么吗?我指出了要这样做的内容。程序的其余部分工作正常,如果出现此错误,则空白输出将被发送回客户端。 (if(strcmp(argv [0],method)!= 0)是if语句)

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

#include "otp.h" 

void error(const char *msg) { perror(msg); exit(1); } // Error function used for reporting issues
/*
    Name: server
    -----------------
    Description:
        This function simulates a server
        Reads buffer input from the client 
        Tokenizes string
        Opens files for writing specified in arguments list
        Calls appropriate function for encrypt/decrypt 
        Sends back an output file

    Parameters: 
        argv[] list from stdin (ex: otp_dec_d or otp_enc_d [port_number])
*/
int server(char* argv[])
{ 
    //printf("%s %s\n", argv[0], argv[1]);    //for testing purposes

    int listenSocketFD, establishedConnectionFD, portNumber, charsRead;
    socklen_t sizeOfClientInfo;
    char buffer[300];
    struct sockaddr_in serverAddress, clientAddress;

    pid_t spawnPid = -5;                            //garbage value

    char method[100];                               //array to hold method name (otp_enc,or otp_dec)
    char input_file_name[100];                      //array to hold input file name
    char key_file_name[100];                        //array to hold key file name

    char output_file_name[300] = "output_file";     //array to hold output file name (output_file)   

    char input[70000];                              //array to hold recv file contents
    char output[70000];                             //array to hold send file contents
    char key[70000];                                //array to hold key file contents

    int port;                                       //int value to hold argv[1]

    // Set up the address struct for this process (the server)
    memset((char *)&serverAddress, '\0', sizeof(serverAddress)); // Clear out the address struct
    portNumber = atoi(argv[1]); // Get the port number, convert to an integer from a string
    serverAddress.sin_family = AF_INET; // Create a network-capable socket
    serverAddress.sin_port = htons(portNumber); // Store the port number
    serverAddress.sin_addr.s_addr = INADDR_ANY; // Any address is allowed for connection to this process

    // Set up the socket
    listenSocketFD = socket(AF_INET, SOCK_STREAM, 0); // Create the socket
    if (listenSocketFD < 0) error("ERROR opening socket");

    // Enable the socket to begin listening
    if (bind(listenSocketFD, (struct sockaddr *)&serverAddress, sizeof(serverAddress)) < 0) // Connect socket to port
        error("ERROR on binding");
    listen(listenSocketFD, 5); // Flip the socket on - it can now receive up to 5 connections

    while(1) {

        // Accept a connection, blocking if one is not available until one connects
        sizeOfClientInfo = sizeof(clientAddress); // Get the size of the address for the client that will connect
        establishedConnectionFD = accept(listenSocketFD, (struct sockaddr *)&clientAddress, &sizeOfClientInfo); // Accept
        if (establishedConnectionFD < 0) error("ERROR on accept");

        spawnPid = fork(); 

        switch(spawnPid) {
            case -1:   
                perror("Hull Breach!\n");
                exit(1);
                break;
            case 0:
                // Get the message from the client and display it
                memset(buffer, '\0', strlen(buffer));
                charsRead = recv(establishedConnectionFD, buffer, strlen(buffer)-1, 0); // Read the client's message from the socket
                if (charsRead < 0) error("ERROR reading from socket");
                //printf("SERVER: I received this from the client: \"%s\"\n", buffer);

                //tokenize input from client 
                char* token = strtok(buffer, "\n"); 
                strcpy(method, token);              //transfer current value to method array  
                token = strtok(NULL, "\n");         //reset token
                strcpy(input_file_name, token);     //transfer current value to input_file_name array
                token = strtok(NULL, "\n");         //reset token
                strcpy(key_file_name, token);       //transfer current value to key_file_name array

                //printf("%s %s %s %s\n", method, input_file_name, key_file_name); //for testing purposes

                //printf("%d\n", port);    //for testing purposes 
                strcat(method, "_d");      //add _d to end of method 

                if(strcmp(argv[0], method) != 0) {
                    fprintf(stderr, "Error: could not contact %s on %s", argv[0], argv[1]); 
                    exit(2);  //SEG_FAULT HERE!!!!!  
                }

                else { 
                    //open input and key files for reading
                    FILE* input_file = fopen(input_file_name, "r"); 
                    FILE* key_file = fopen(key_file_name, "r"); 

                    //transfer file contents to arrays
                    fgets(input, 70000, input_file); 
                    fgets(key, 70000, key_file); 

                    //close files
                    fclose(input_file); 
                    fclose(key_file);

                    //remove trailing newlines from arrays
                    input[strcspn(input, "\n")] = '\0'; 
                    key[strcspn(key, "\n")] = '\0';

                    //printf("%s\n%s\n", input, key);     //for testing purposes
                    //printf("%s\n", argv[0]); 

                    //printf("%s\n", method);            //for testing purposes 

                    /* --------------------- Handle encrypt v. decrypt --------------------- */ 
                    //if argument 1 in argv array is encrypt 
                    if(strcmp("otp_enc_d", method) == 0)
                        encrypt(input, output, key); 

                    //else if argument 1 in argv array is decrypt 
                    else if(strcmp("otp_dec_d", method) == 0)
                        decrypt(input, output, key);   

                    /* ------------------- End handle encrypt v. decrypt ------------------- */ 
                }

                //printf("%s\n", output);             //for testing purposes

                //Open output file and write contents to it 
                FILE* output_file = fopen(output_file_name, "w+");
                fprintf(output_file, "%s", output); 

                // Send a Success message back to the client
                charsRead = send(establishedConnectionFD, output_file_name, strlen(output_file_name), 0); // Send success back
                //printf("%d\n", charsRead); 
                if (charsRead < 0) error("ERROR writing to socket");

                // Close the existing socket which is connected to the client
                close(establishedConnectionFD); 
                establishedConnectionFD = -1; 
                exit(0); 
                break; 

            default: ;
        }
                close(establishedConnectionFD); 
                establishedConnectionFD = -1;
                wait(NULL); 
    }

    close(listenSocketFD); // Close the listening socket

    return 0; 
}

0 个答案:

没有答案
相关问题