Home > Software design >  C UNIX Help - simple TCP server socket connection
C UNIX Help - simple TCP server socket connection

Time:12-02

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"

CodePudding user response:

You problem is here:

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)); << Change strlen(buffer)
    strcat(buffer, "\n");
    if(write(connSock, buffer, strlen(buffer)) < 0)
    { perror("write"); exit(EXIT_FAILURE); }
    close(fd);
}

strlen(buffer) can be any value, because you are initializing buffer to 1024 bytes. The memory area is possibly being filled full of zeroes. strlen(buffer) would then be returning 0, because the first character is a null byte. Nothing is being written into the buffer because read will end up writing zero bytes.

  • Related