Отправить большие файлы через сокет в C - PullRequest
4 голосов
/ 30 декабря 2011

Я пишу простой FTP-сервер для школьного проекта.Проект почти завершен, единственная проблема, которую я имею, это отправка файла через сокет клиенту.Я не могу записать в сокет более 200 КБ данных, небольшие файлы успешно загружены.Может кто-нибудь сказать мне, как правильно отправлять большие файлы через сокеты Linux?

Заранее спасибо.

PS Я использую C и 32-битный Linux, сервер работает в режиме PORT,использует низкоуровневые операции открытия, записи, чтения и другие функции, такие как sendfile, send, sendto.

Ответы [ 2 ]

5 голосов
/ 30 декабря 2011

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

fd = open(filename, O_RDONLY);
struct stat s;
fstat(fd, &s); // i get the size
adr = mmap(NULL, s.st_size, PROT_READ, MAP_SHARED, fd, 0); // i get the adress
write(socket, adr, s.st_size); // i send the file from this adress directly

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

4 голосов
/ 30 декабря 2011

Одной из идей может быть чтение фрагмента файла по фрагменту, например:

Псевдокод

#define CHUNK_SIZE 1000

void send(){
  uint8_t buff[CHUNK_SIZE];
  int actually_read;
  while((actually_read = read(fd, buff, sizeof(buff)) > 0)
     sendto(sock_fd, buff, actually_read, 0);
}

Вы должны добавить некоторую проверку ошибок, ноИдея состоит в том, чтобы прочитать значительное количество байтов из файла, который вы хотите отправить, и отправить это количество.На стороне сервера вы должны сделать то же самое, читая из сокета прибывающие куски и записывая их в файл.Возможно, вы захотите добавить префикс некоторых метаданных к buff, просто чтобы сообщить серверу, какой файл вы передаете, если вы хотите обрабатывать несколько передач файлов.Поскольку FTP использует TCP, вы не должны беспокоиться о потере данных.

Опять же, это всего лишь идея.Я полагаю, есть несколько способов сделать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...