2010-12-08 2 views
0

У меня есть задача в школе написать FTP-программу на языке C (для Linux). Я получил все базовые функции, работающие в кратчайшие сроки (ls, cd), но у меня возникают проблемы с частью передачи файлов. Я использую SendFile для отправки файла через сокет так:Отправка файла через сокет в C

int fd = open(temp, O_RDONLY); 
int rc = sendfile (client_fd, fd, &offset, statbuf.st_size); 

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

while((i = read(sock, message, MSG_LEN - 1)) > 0) { 

    message[i] = '\0'; 
    printf("%s", message); 
} 

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

Я ценю любые предложения!

+0

Возможно, попробуйте отправить файл еще раз, с дескриптором сокета, являющимся входом, и файлом, открытым для записи в качестве вывода ...? – 2010-12-08 01:41:25

+2

BTW/двоичные файлы могут содержать 0 байтов, которые C-style функции, такие как printf, могут ошибочно использоваться для терминаторов ASCIIZ NUL, а также другие значения, которые соответствуют кодам управления ASCII для очистки экрана, перемещения курсора и т. Д. Вы должны распечатать файл байт побайта в шестнадцатеричном формате или использовать другой способ сделать его понятным для человека и совместимым с терминалом. – 2010-12-08 01:43:33

ответ

2

Вам нужно выключать пишущую сторона сокета после отправки файла, так что приемник знает конец файла достигнут:

shutdown(client_fd, SHUT_WR); 

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

Ваша сторона чтения тогда увидит конец файла (read() возвращение 0), после чего он должен close() его конец сокета. Затем сервер увидит конец файла, и он также может закрыть свой сокет (и записать успешную передачу).

Смежные вопросы