Консультация № 171081
05.08.2009, 14:32
0.00 руб.
0 6 0
Делаю FTP сервер на Delphi (Клиент - Internet Explorer)
использую ServerSocket1, с идентификацией пользователя, скачивание файлов от сервера клиентом - работает.
Но вот с отправкой файла от клиента на сервер просто беда.
как понимаю, принимать файл надо по событию TForm1.ServerSocket3ClientRead считывая передаваемый файл из Socket.ReceiveBuf, но как определить что клиент передал весь файл не зная его размера - не понимаю



Обсуждение

Неизвестный
05.08.2009, 14:46
общий
если с сервера к клиенту тогда ServerSocket1ClientRead
если от клиента к серверу тогда ServerSocket1ClientWrite
Неизвестный
05.08.2009, 21:30
общий
Модераторы:
Удалите пожалуйста ответ неверно понял вопрос
давно
Модератор
18584
3280
05.08.2009, 21:35
общий
VolRus:
сделано
Неизвестный
06.08.2009, 13:13
общий
Если я правильно понял вопрос, вы делаете полноценный FTP-сервер - значит должны соответствовать спецификациям (RFC 959). Т.е. по управляющему каналу получаете STOR, открываете дата-канал, отвечаете "150" и ждете пока не получите все данные (до закрытия) из дата-канала, после чего отвечаете "226". При данной схеме знать размер получаемого файла необязательно - получаете все что придет, пока канал данных не закроется.

P.S. А может вы все-таки не FTP-сервер делаете? А сервер работы с файлами по HTTP? Просто по тексту вашего вопроса возникли сомнения, что это FTP :).
Неизвестный
07.08.2009, 09:25
общий
PavelGM:
Вы поняли правильно, это именно FTP сервер.
получив команду STOR я открываю порт в сокете приема данных, а в командный отсылаю "150 Opening BINARY mode data connection."
Но принять файл не получается - сказывается отсутствие опыта работы с потоками(файл нужно считывать из буфера и добавлять в конец потока, а при окончании приема записать в файл на диске с именем из комманды STOR.)
В том то и трудность что не понятно где трабла в работе с потоком или в работе с сокетом
Неизвестный
07.08.2009, 12:54
общий
Обычно делаю так (у меня не FTP, но использую похожую схему с двумя сокетами для своих программ) - считываю ReceiveLength - в нем длина текущей посылки. Дальше копируем ReceiveBuf в TMemoryStream (либо сразу в TFileStream, что удобнее если все равно файл нужен, а кэширование нынче в системах и так хорошо работает) и ждем следующего OnClientRead. И так пока все не принимаем - в OnDisconnect или OnError для дата-сокета закрываем TMemoryStream и сбрасываем в файл (или просто закрываем TFileStream).

P.S. Если так и делаете, а что-то не работает, приведите код из OnClientRead для дата-сокета и того места, где открываете/создаете буфер для принимаемого файла, может это прольет свет на проблему :).
Форма ответа