C++ UNIX Help – simple TCP server socket connection

  c++, linux, tcp, unix

I am a student writing a C++ code using UNIX system calls to perform simple server <-> client requests from the Terminal. The user (me) input in the port for both programs (Server and Client) in the Terminal to establish a connection, the goal is for the Server to send back to the Client the contents of what the Client program input in.

I.e:

Terminal 1:
./server 9000

Terminal 2:
./client localhost 9000 ~

Will show a list of all directories and files in Home.

Or
Terminal 2: ./client localhost 9000 test.txt

Will read contents from the test.txt file and write it onto the Client’s terminal.

As of now, only folders work. Whenever I try a file instead, it prints a blank line. This is my code for the process function:

void processClientRequest(int connSock)
{
    int received;
    char path[1024], buffer[1024];
    
    // Read from the client
    if((received = read(connSock, path, sizeof(path))) < 0)
    { perror("receive"); exit(EXIT_FAILURE); }
    
    // Check if it is a directory or a file
        struct stat s;
        if(stat(path,&s) == 0 )
        {
            // It is a directory
            if(s.st_mode & S_IFDIR)
            {
                DIR *dirp = opendir(path);
                if (dirp == 0)
                {
                    // Tell client they gave the inappropriate input
                    // Duplicate socket descriptor into error output
                    // Then print it to client's end with perror to
                    // Give more in-depth details of the error to user
                    close(2);
                    dup(connSock);
                    perror(path);
                    exit(EXIT_SUCCESS);
                }
            
                struct dirent *dirEntry;
                while((dirEntry = readdir(dirp)) != NULL)
                {
                    // If statement to hides all files/folders that start with a dot
                    // Which are hidden files/folders
                    if(dirEntry->d_name[0] != '.')
                    {
                        strcpy(buffer, dirEntry->d_name);
                        strcat(buffer, "n");
                        if(write(connSock, buffer, strlen(buffer)) < 0)
                        { perror("write"); exit(EXIT_FAILURE); }
                    }
                }
                closedir(dirp);
                close(connSock);
                exit(EXIT_SUCCESS);         
            }
            // It is a file
            else if(s.st_mode & S_IFREG)
            {
                int fd = open(path, O_RDONLY);
                if(fd < 0) { perror("open"); exit(EXIT_FAILURE); }
                read(fd, buffer, strlen(buffer));
                strcat(buffer, "n");
                if(write(connSock, buffer, strlen(buffer)) < 0)
                { perror("write"); exit(EXIT_FAILURE); }
                close(fd);
            }
            // Not a file or directory
            else
            {
                cout << "It is neither a file nor directory!" << endl;
                exit(EXIT_FAILURE);
            }
        }
    
        else
        {
            // Same explanation as line 95 - 98
            close(2);
            dup(connSock);
            perror("stat");
            exit(EXIT_SUCCESS);
        }
    close(connSock);
    exit(EXIT_SUCCESS);
}

As a side question, how do I get it to accept/recognize a codeword before executing the process as well as the double quotes? As of now I can only use ./client … pathname/"name with spaces" ; if I use ./client … "pathname/name with spaces" it displays a stat: no such file or directory error.
For example:

./client localhost 4000 "GET pathname/filename"

Source: Windows Questions C++

LEAVE A COMMENT