Проблема с программой, включающей сокеты и связь клиент-сервер в C - PullRequest
1 голос
/ 08 июня 2019

Я работаю над программой на C, которая включает в себя клиент-серверные соединения и связь между двумя сторонами.

Программа предполагает отправку письма клиенту на сервер и получение письма сервером. Затем сервер ищет в текущем каталоге файлов (в linux) файл, начинающийся с этой буквы, и отправляет клиенту количество байтов файла и текст файла.

Общая программа очень длинная, и для задания инструктор уже выполнил большую часть кода, такого как настройка сокетов и создание всей программы для клиентской части операций.

Для серверной части мне пришлось написать код для:

  • получение дескриптора файла из переданной памяти и приведение к нему

- получение письма от клиента

-Попытка открыть текущий каталог

-Итерация по каталогу в поисках файла, начинающегося с буквы

-Попытка открыть файл и отправить размер файла и количество байтов файла клиенту в сетевом порядке

-Закрытие файла и каталога после окончания

-Ошибка проверки: есть операторы проверки ошибок, если каталог не может быть открыт, файл не может быть открыт или не найден соответствующий файл

Ниже приведен мой код с комментариями

void*           handleClient    (void*  vPtr
                                )
{
  //  I.  Application validity check:

       int      fd              = *((int *) vPtr); 
     //casting vPtr to an int//

        free(vPtr);


//  II.  Handle the client:

        char buffer[BUFFER_LEN+1];
        read(fd, buffer, BUFFER_LEN+1);
        //read the letter into a buffer//

        const char* dirNamePtr = ".";
        DIR* dirPtr = opendir(dirNamePtr);
//   Open the current directory


        if (dirPtr == NULL)
        {
            int toSend = htonl(CANT_READ_DIR_CODE);
                write(fd,&toSend,sizeof(toSend));
                printf("Cannot read directory\n");
                return(NULL);
        }
// If current directory cannot be opened, it sends a error message in network // endian to the client

        struct dirent* entryPtr;
        char path[BUFFER_LEN];
        struct stat statBuffer;
//implements struct dirent to get info on the directory

//iterates through the directory
        while ((entryPtr=readdir(dirPtr)) != NULL)
        {


           stat(entryPtr->d_name, &statBuffer);
//puts in metaddata of the current directory into statbuffer


          if (!S_ISREG(statBuffer.st_mode))
                continue;
//if the entry is not a file, continue

// if the first letter of the file is not the character received from the //client, send an error mesage

          if(entryPtr->d_name[0]!=buffer[0])  {
                   int toSend2 = htonl(NO_MATCH_CODE);
                   write(fd,&toSend2,sizeof(toSend2));
                   printf("No matching file\n");
                   return(NULL);
               }


                int ab;
                int numRead;
                int numBytes;
                char buffer[BUFFER_LEN];
//open the file and send bytes of file and file size to client

            if (entryPtr->d_name[0]==buffer[0] &(S_ISREG(statBuffer.st_mode)))
                {

                        ab=open(entryPtr->d_name,O_RDONLY,0660);

                        if(ab<0) {
                                int toSend3 = htonl(CANT_READ_FILE_CODE);
                                write(fd,&toSend3, sizeof(toSend3));
                                printf("Cannot read <filename>\n");
                                return(NULL);
                                }

                        numBytes=htonl(statBuffer.st_size);
                        write(fd, &numBytes, sizeof(numBytes));

                        printf("Sending %s, %d bytes\n",entryPtr >d_name,statBuffer.st_size);


                while((numBytes=read(ab,buffer,BUFFER_LEN))>0)
                        {
                                printf("We read %d bytes\n", numBytes);
                                write(fd, buffer, numBytes);
                        }
//close the fiel

                       close(ab);

                }
                break;

//leave the loop





}

 //  III.  Finished:
//

closedir(dirPtr);

return(NULL);
}

Мой код компилируется, но не отправляет файл клиенту, когда я пытаюсь его запустить. Я пробовал несколько разных писем, и ни для одного из них это не сработало. Я не совсем знаю, в чем проблема, которая затрудняет исправление моих ошибок.

Я не прошу ответа или чего-либо еще, просто помогаю понять, в чем я не прав. Я ценю любую помощь.

1 Ответ

0 голосов
/ 08 июня 2019

Ваша логика того, когда отправлять и когда отправлять статус без файла, кажется неправильной.Я думаю это должно быть так (честное предупреждение, я не проверял это, или даже не компилировал его, кроме базовой проверки синтаксиса, но вы должны понять):

void* handleClient(void*  vPtr)
{
    //  I.  Application validity check:
    int fd = *((int *) vPtr);
    free(vPtr);

    //  II.  Handle the client:
    char buffer[BUFFER_LEN+1];
    read(fd, buffer, BUFFER_LEN+1);
    //read the letter into a buffer//

    const char* dirNamePtr = ".";
    DIR* dirPtr = opendir(dirNamePtr);
    //   Open the current directory

    if (dirPtr == NULL)
    {
        int toSend = htonl(CANT_READ_DIR_CODE);
        write(fd,&toSend,sizeof(toSend));
        printf("Cannot read directory\n");
        return(NULL);
    }

    struct dirent* entryPtr;
    char path[BUFFER_LEN];
    struct stat statBuffer;
    //implements struct dirent to get info on the directory

    //iterates through the directory
    while ((entryPtr=readdir(dirPtr)) != NULL)
    {
        stat(entryPtr->d_name, &statBuffer);
        //puts in metaddata of the current directory into statbuffer

        // if this isn't a regular file OR the first char doesn't match...
        if (!S_ISREG(statBuffer.st_mode) || entryPtr->d_name[0]!=buffer[0])
            continue;

        int ab;
        int numRead;
        int numBytes;
        char buffer[BUFFER_LEN];
        //open the file and send bytes of file and file size to client

        ab = open(entryPtr->d_name,O_RDONLY,0660);

        if(ab<0) {
            int toSend3 = htonl(CANT_READ_FILE_CODE);
            write(fd,&toSend3, sizeof(toSend3));
            printf("Cannot read <filename>\n");
            closedir(dirPtr);
            return(NULL);
        }

        numBytes=htonl(statBuffer.st_size);
        write(fd, &numBytes, sizeof(numBytes));

        printf("Sending %s, %d bytes\n",entryPtr >d_name,statBuffer.st_size);
        while((numBytes=read(ab,buffer,BUFFER_LEN))>0)
        {
            printf("We read %d bytes\n", numBytes);
            write(fd, buffer, numBytes);
        }

        //close the file and leave
        close(ab);
        break;
    }

    // if this is NULL it means we dind't send anything. we break the loop
    //  when a file to send it discovered.
    if (entryPtr == NULL)
    {
        printf("No matching file\n");
        int toSend2 = htonl(NO_MATCH_CODE);
        write(fd, &toSend2, sizeof(toSend2));
    }

    //  III.  Finished:
    closedir(dirPtr);

    return(NULL);
}
...