Сокеты не отправляют все двоичные данные - PullRequest
0 голосов
/ 29 декабря 2010

На самом деле я работаю на очень простом FTP-сервере.Теперь у меня проблема с отправкой файла (RETR в протоколе FTP).Я использую сокеты и бинарный режим в моем клиенте.Файлы с текстом отправляются отлично, но проблема в двоичных файлах (изображения и т. Д.).

Вот фрагмент моего кода:

FILE *fin=fopen(fileloc,"rb");

if(fin != NULL){
    fpos_t filelen;

    fseek (fin, 0, SEEK_END);
    fgetpos (fin, &filelen);

    fseek (fin, 0, SEEK_SET);
    printf("Sending file %s (%d b)", fileloc, filelen);
    sprintf(sbuffer,"150 Opening BINARY mode data connection for file transfer.\r\n");
    bytes = send(ns, sbuffer, strlen(sbuffer), 0);
    byte temp_buffer[512];

    long int totalsent;
    totalsent = 0;

    while (!feof(fin)){

        memset(temp_buffer, '\0', sizeof(sbuffer));

        fgets((char *)temp_buffer, sizeof(sbuffer), fin);

        if (!active) bytes = send(ns_data, (char *)temp_buffer, strlen(sbuffer), 0);
        else bytes = send(s_data_act, (char *)temp_buffer, strlen(sbuffer), 0);

        totalsent = totalsent + bytes;

        printf("     file size = %d, send = %d bytes, strlen = %d, total = %d, left = %d\n",
               filelen, bytes, strlen(sbuffer), totalsent, filelen-totalsent);
        }

    fclose(fin);
    sprintf(sbuffer,"250 File transfer completed... \r\n");
    bytes = send(ns, sbuffer, strlen(sbuffer), 0);
}

Мой FTP-клиент получает неполные файлы с различиями внутриоткройте файлы в Блокноте для сравнения), как вы могли видеть на этом изображении на экране, если URL работал без входа в систему:

http://i53.tinypic.com/2wcjtdk.jpg

Существуют также различия в размере файла -исходный файл занимает около 7 КБ, а отправленная копия - на 1 КБ меньше.Я использовал очень другой FTP-клиент, и проблема та же.

1 Ответ

5 голосов
/ 29 декабря 2010

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

...