2013-05-03 2 views
0

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

Вот где я посылаю требуемый файл

while(!feof(requestedfile)) { 
    bytes_read = fread(buf, 1, sizeof(buf), requestedfile); 
    send(clientSock, buf, bytes_read, 0); 

} 

Когда я пытаюсь скачать, я следующий

while(recv(clientSock, currentLinePointer, 1, 0) != 0) { 
    currentLinePointer++; 
} 

Я новичок в C, но я знаю, что у меня есть 2 вопроса

  1. Как выполнить более эффективное чтение? Если я читаю 1024 байта за раз, на последнем блоке данных может быть только половина из 1024 байтов. Будут ли другие 512 бессмысленных байт вызывать ошибки в моем файле? (Я знаю, что плохие вещи случаются с картинками, когда вы пытаетесь прочитать и сохранить jpg с бессмысленными байтами в конце)
  2. Теперь, когда я прочитал файл, как мне сохранить этот файл? Скажите запрос сверстника «hello.jpg». Установка у меня может отправлять и читать файл, но теперь, как я могу сохранить этот файл в каталог, запрашивающего сверстники «PATH/Фотографии /»
+0

Помните, что 'recv' возвращает количество фактически полученных байтов, -1 при ошибке и 0 при закрытом соединении. Это может помочь сделать блокировку неблокирующей. –

+0

Что касается сохранения в «правильной» папке, либо изменить протокол, чтобы программа отправки сначала отправила путь, либо установила его в принимающей программе. –

+0

Было бы более эффективно использовать sendfile (2) на обоих концах (http://linux.die.net/man/2/sendfile) –

ответ

1

http://msdn.microsoft.com/en-us/library/windows/desktop/ms740121(v=vs.85).aspx

Если не происходит никакой ошибки, ПРИЕМ возвращается количество полученных байтов

Вам нужно знать, что такое возвращаемое значение recv и записывать только это количество байтов в ваш файл.

+0

ok, но как только я прочитал во всех байтах этого файла, как мне сохранить этот файл? – user2158382

0

Я предлагаю вам прочитать 4096 байт за один раз, так как это стандартный размер сектора диска в наше время (http://en.wikipedia.org/wiki/Disk_sector):

char* buffer = (char*)malloc(4096), *position = buffer; 

while((bytes_read = recv(clientSock, position, 4096, 0) > 0) 
{ 
    if(fwrite(position, 1, bytes_read, localFile) != bytes_read) 
    { 
     // do some error handling here 
     break; 
    } 
    position += 4096; 
} 

// and here 

free(buffer); 
+0

Вы всегда можете проверить размер блока, вызвав 'stat()' 'в файле, а затем проверив поле' 'st_blksize' '' stat stat ''. –

0

recv() возвращает число полученных байтов, 0, если соединение закрывается и -1 по ошибке. Это в основном отвечает на ваш вопрос.

Вы также должны отслеживать значение, возвращаемое send(). Он возвращает количество отправленных байтов или, наконец, помещает буфер для отправки. Он не всегда отправляет все, что вы скажете,, если буфер заполнен или соединение потеряно. Следите за его возвращаемым значением, чтобы контролировать использование буфера отправки и избегать пробелов в передаваемом файле. Возможно, вам придется выполнить новый вызов send(), чтобы отправить часть данных, которые она отказала при предыдущем вызове.