TCP отправляет данные файла от клиента к проблеме сервера: другая контрольная сумма в файле

Я пытаюсь передать данные размером около 100 МБ через сокет соединения TCP ipv4.

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

После отправки файла данных на сервер, и сервер записывает его в новый файл, я снова вычисляю контрольную сумму и вижу другое.

Я думаю, вероятно, с моими функциями отправки и получения.

Функция Sender, используемая в CLIENT:

void send_file(FILE *fp, int sockfd) {
    int n;
    char data[SIZE] = {0};

    while (fgets(data, SIZE, fp) != NULL) {
        if (send(sockfd, data, sizeof(data), 0) == -1) {
            perror("[-]Error in sending file.");
            exit(1);
        }
        bzero(data, SIZE);
    }
}

Функция Writer используется на СЕРВЕРЕ:

    void write_file(int sockfd, char *filename) {
    int n;
    FILE *fp;
    //char *filename = "new_data.txt";
    char buffer[SIZE];

    fp = fopen(filename, "w");
    while (1) {
        n = recv(sockfd, buffer, SIZE, 0);
        if (n <= 0) {
            break;
            return;
        }
        fprintf(fp, "%s", buffer);
        bzero(buffer, SIZE);
    }
}

Вы должны использовать fread() и fwrite() вместо fgets() и fprintf(). И проверьте результат fread(), он сообщает вам, сколько байтов вы прочитали, поэтому вы должны отправлять только это количество байтов.

pmacfarlane 06.12.2022 18:43

Ниже есть хороший совет. Но вам, вероятно, нужно вызывать fopen с "rb" и "wb" в Windows, чтобы \r\n не переводилось в текстовом потоке.

selbie 06.12.2022 23:13

Вызов bzero() — это карго-культовая трата циклов, и, в любом случае, он не подходит для обнуления буфера при первом проходе. Вам не нужно рассматривать буфер cintent как строку, заканчивающуюся NUL, потому что вы знаете 'n'. Я видел этот код несколько раз, и все с одними и теми же проблемами. Скопируйте свой код из лучшего источника.

Martin James 07.12.2022 02:26

Примечание: очень жаль, что вы удалили свой вопрос о слишком медленных каналах. Как следствие, это единственный способ связаться с вами. 2 часа - не слишком большой срок, чтобы оставить вопрос поднятым. Я только что закончил ответ. Мое решение заняло 0,1 секунды для 100 МБ со скоростью 653 МБ/с. Вы можете «восстановить» свой вопрос, если вам все еще нужна помощь [или задать новый и ответить мне здесь, чтобы предупредить меня]

Craig Estey 09.12.2022 20:37

@CraigEstey Мне очень жаль, я думал, что это больше не актуально, если вы можете мне помочь, я буду признателен и учусь на этом stackoverflow.com/questions/74746348/…

ATB 09.12.2022 20:55
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

fgets() и fprintf() используются для чтения и записи строк с завершающим нулем, а не произвольных двоичных данных. fread() и fwrite() здесь ваши друзья. Что-то вроде:

Клиент:

#define CHUNK_SIZE 1024
char buffer[CHUNK_SIZE];

while ((num_bytes = fread(buffer, 1, CHUNK_SIZE, fp)) > 0)
{
    send(sockfd, buffer, num_bytes, 0);
}

Сервер:

// Same chunk size and buffer as above

while ((num_bytes = recv(sock, buffer, CHUNK_SIZE, 0)) > 0)
{
    fwrite(buffer, 1, num_bytes, fp);
}

Технически fwrite() и send() могут записать меньше байтов, чем вы их просите, и вам действительно следует зацикливаться, пока все байты не будут записаны.

Вы также должны технически открывать свои файлы в режимах «rb» и «wb» для двоичных файлов.

Windows также нуждается в передаче режима "b". то есть "rb" и "wb" в вызове fopen.

selbie 06.12.2022 23:14

@pmacfarlane я перехожу на ваш код, и я меняю fopens на rb и wb и все еще другую контрольную сумму, но файл выглядит равным, я не знаю, в чем проблема

ATB 06.12.2022 23:30

Размеры файлов совпадают? Как дела с контрольной суммой? В коде или с помощью внешнего инструмента, такого как sha256sum или md5sum?

pmacfarlane 06.12.2022 23:31

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

ATB 06.12.2022 23:35

Какую ОС вы используете? Если Linux, запустите md5sum и/или sha256sum для обоих файлов и посмотрите, совпадают ли они. Если они это сделают, в вашей функции есть ошибка. Что было бы отдельным вопросом :-D.

pmacfarlane 06.12.2022 23:36

@pmacfarlane Я работаю на Windows WSL Ubuntu 22.04, я могу отредактировать этот пост и добавить функцию контрольной суммы.

ATB 06.12.2022 23:37

Вы почти наверняка должны иметь sha256sum и md5sum в WSL. Если ничего другого, у вас должна быть программа под названием «cksum». Попробуйте и посмотрите. Я думаю, что ваш код контрольной суммы - это новый вопрос.

pmacfarlane 06.12.2022 23:38

@pmacfarlane stackoverflow.com/questions/74709938/…

ATB 06.12.2022 23:55

Другие вопросы по теме