Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

стабильный и мощный FTP - реально? [D7]


Страницы:   1 2

istok ©   (2007-12-11 21:13:00) 

Надо пересылать файлы с клиентских модулей программы на серверный. Используем для этого ftp. Надо обеспечить бесперебойную работу системы при 3х тысячах клиентов и сотнях файлов по ~2Кб. Причём всё должно работать (не обязательно быстро, но надёжно) в случае если все клиенты приконнектятся одновременно и будут слать данные.

Это реально?

Тесты indy, ics с серверами на indy, ics, file zilla не дают 100% гарантии доставки каждого файла.

То есть операция Put иногда не проходит. И для этого достаточно 2-4х клиентов, постоянно отсылающих файлы.

ics и indy сервера вообще убиваются после определенного времени.

Может фтп для таких задач не очень годится или надо специальное что-то делать или я что-то не понимаю? (ведь фтп сервера в инете как-то работают с тысячами клиентов?)

В идеале я хочу чтоб любой файл мог быть доставлен, если сервер доступен. И ничего при этом не глючило.


umbra   (2007-12-13 15:51:00) [1]


> 30000 копий одного и того же процесса со всеми ресурсами
> занятыми для каждого процесса отдельно.

fork не занимает новых ресурсов, кроме памяти, разве что, он передает процессу копии открытых дескрипторов родительского процесса.


Slym   (2007-12-13 11:56:00) [2]

tesseract ©   (13.12.07 10:22) [37]
к тому же 30000*2 сокетов (команды+данные) т.е. близко к пределу MaxWord, а если в пассиве то ваще 30000*3 (команды+данные_серверн+данные_клиент) сокетов что уже больше MaxWord


tesseract   (2007-12-13 10:22:00) [3]


> Ну вот я и спрашиваю, что же это получается для 30000 юзеров
> будет 30000 копий одного и того же процесса со всеми ресурсами
> занятыми для каждого процесса отдельно.


Ну и что ? Работает же, во всех Unix. И не всё копируеться. Занятые файловые дескрипторы тебе же не надо копировать ? да и 30 тысяч юзеров одновременно навряд-ли ломануться на FTP - канал столько твой не выдержит. Даже 1 гигабит/30000 =34 килобита.


DVM   (2007-12-12 23:00:00) [4]


> Функция Fork полностью клонирует процесс, со всеми данными
> и состоянием

Ну вот я и спрашиваю, что же это получается для 30000 юзеров будет 30000 копий одного и того же процесса со всеми ресурсами занятыми для каждого процесса отдельно. Что то как то расточительно. Оно вообще работать то будет?


tesseract   (2007-12-12 22:55:00) [5]


> В общем это клонирование, но в Линуксе многое взяли из Виндоус


А не наоборот ?


> Кстати, а под Unix не знаете как реализуется подобное? Там
> ведь насколько я знаю вообще процесс сервера клонируется
> особым образом для каждого клиента.


Функция Fork полностью клонирует процесс, со всеми данными и состоянием. Поэтому там все попроще. Fork вообще крайне полезная функция, чего ее в винду не ввели ?


Anatoly Podgoretsky   (2007-12-12 20:02:00) [6]

> istok  (12.12.2007 20:00:33)  [33]

Провести отладку.


istok   (2007-12-12 20:00:00) [7]


> Это AV не из недр ics, а из NTDLL - ты туда передаешь недопустимые
> параметры.


может не я, а ics? я-то тут причём? :)

итого - что надо сделать, чтоб такой косяк пофиксить? править ics?


Anatoly Podgoretsky   (2007-12-12 19:55:00) [8]

> istok  (12.12.2007 19:54:31)  [31]

Это AV не из недр ics, а из NTDLL - ты туда передаешь недопустимые параметры.


istok   (2007-12-12 19:54:00) [9]

Anatoly Podgoretsky ©   (12.12.07 19:12) [29][30]

а, значит я вас изначально не совсем верно понял, подумав что на сервере совсем не будет ошибок.

но такое AV из недр ics это разве нормально? оно не проходит без последствий и после этого только перезапуск процессе\службы помогает. Делать перезапуски службы каждые 10минут это ж бред.. не?

by the way:
а насчёт того что Put'ы часто не срабатывали я нашел ответ в малом диапазоне pasv портов сервера.


Anatoly Podgoretsky   (2007-12-12 19:13:00) [10]

> istok  (12.12.2007 19:04:28)  [28]

Примеры не обладают никакой живучестью, они примеры.


Anatoly Podgoretsky   (2007-12-12 19:12:00) [11]

> istok  (12.12.2007 17:18:23)  [23]

Особенность одна, все и везде должно быть обернуто в try except end, что бы любые ошибки не уронили сервер, он должен выживать в самых тяжелых условиях.


istok   (2007-12-12 19:04:00) [12]


> MetalFan ©   (12.12.07 18:43) [27]
>
> в 17 строке


Могу конечно скинуть код примера фтп сервера от ics, только вряд ли в нём будут явные ошибки :)

Что тут можно придумать?


MetalFan   (2007-12-12 18:43:00) [13]

в 17 строке


istok   (2007-12-12 18:06:00) [14]

лол, стандартная демка от ics под нагрузкой тоже выдаёт "-AnswerToClient
> 127.0.0.1 500 PASV exception: 'Access violation at address 7C92BD02 in module 'ntdll.dll'. Read of address 00000001'.
-ClientCommand"

просто на разных машинах по-разному ловится.

нагрузка - 3 клиента.

в чем тут может быть косяк?


MetalFan   (2007-12-12 17:37:00) [15]


> Anatoly Podgoretsky ©   (12.12.07 15:29) [20]
>
> Система тоже не создает, это стандартный WinSock работает
> на сообщениях, а не потоках.

Создает. но использует для этого специальные механизмы. как может асинхронность в ОДНОМ потоке работать???


istok   (2007-12-12 17:19:00) [16]

P.S.:  AddLog я отключил, он ничего не делает.


istok   (2007-12-12 17:18:00) [17]

Ситуация такая. Ниже приведен код службы сервера, которая при нагрузочном тестировании быстро падает.

Под падением понимается
-неожиданный вызов TFtpServer.OnStop
-запись "Ошибка приложения weServerDataTransfer.exe, версия 2.1.0.340, модуль ntdll.dll, версия 5.2.3790.3959, адрес 0x0002a754. Дополнительные сведения можно найти в центре справки и поддержки, в " http://go.microsoft.com/fwlink/events.asp"." в журнале ошибок

Когда ровно также тестирую аналогичную демку ics ftp server'a от автора - она не падает.

Может есть какие-то особенности при реализации ics сервера в службе?
Или данный код кривой?

procedure TweServerDataTransferService.FtpServer1Authenticate(Sender: TObject;
 Client: TFtpCtrlSocket; UserName, Password: TFtpString;
 var Authenticated: Boolean);
begin
 Authenticated := (UserName = 'admin') and (PassWord = 'we_pass');

 if Authenticated then
 begin
   AddLog('User authenticated: ' + Client.GetPeerAddr + ', User ''' + UserName);

   //Client.HomeDir := FweFolders.dirServerLogs;
   //ForceDirectories(Client.HomeDir);
 end
 else
   AddLog('User NOT authenticated: ' + Client.GetPeerAddr + ', User ''' + UserName);
end;

procedure TweServerDataTransferService.FtpServer1ClientConnect(Sender: TObject;
 Client: TFtpCtrlSocket; AError: Word);
begin
 AddLog('! ' + Client.GetPeerAddr + ' connected');

 if Error <> 0 then
 begin
   Client.Close;
   AddLog('quick close: FtpServer1ClientConnect');
 end;
end;

procedure TweServerDataTransferService.FtpServer1ClientDisconnect(Sender: TObject;
 Client: TFtpCtrlSocket; AError: Word);
begin
 AddLog('! ' + Client.GetPeerAddr + ' disconnected');
end;

procedure TweServerDataTransferService.FtpServer1RetrDataSent(Sender: TObject;
 Client: TFtpCtrlSocket; Data: TWSocket; AError: Word);
begin
   if Error <> 0 then
       AddLog('! ' + Client.GetPeerAddr
       + ', ['+ Client.UserName + '], ' +
                          ' Data sent. Error #' + IntToStr(Error));

   if Error <> 0 then
   begin
     Client.Close;
     AddLog('quick close: FtpServer1RetrDataSent');
   end;
end;

procedure TweServerDataTransferService.FtpServer1RetrSessionClosed(Sender: TObject;
 Client: TFtpCtrlSocket; Data: TWSocket; AError: Word);
begin
 if (AError = 0) then
 begin
   if Client.AllSent then
     //FilesSent := FilesSent + 1
   else
     Addlog('FtpServer1RetrSessionClosed: ALL_SENT=FALSE '+Client.GetPeerAddr  + ', ['+ Client.UserName + ']');
 end
 else
   AddLog('FtpServer1RetrSessionClosed: '+ ' ['+ Client.UserName + '], ' +'error = ' + IntToStr(AError));

   if AError <> 0 then
   begin
     Client.Close;
     AddLog('quick close: FtpServer1RetrSessionClosed');
   end;
end;

procedure TweServerDataTransferService.FtpServer1RetrSessionConnected(Sender: TObject;
 Client: TFtpCtrlSocket; Data: TWSocket; AError: Word);
begin
   if Error <> 0 then
       AddLog('! ' + Client.GetPeerAddr
       + ', ['+ Client.UserName + '], ' +
                          ' Data session connected. Error #' + IntToStr(Error)
                          + ' AllSent = ' + BoolToStr(Client.AllSent, True));

   if (Error = 0) and Client.AllSent then
     Addlog('All Sent - ok');

   if Error <> 0 then
   begin
     Client.Close;
     AddLog('quick close: FtpServer1RetrSessionConnected; error = ' + IntToStr(Error));
   end;
end;

procedure TweServerDataTransferService.FtpServer1Start(Sender: TObject);
begin
 AddLog('! Server started');
end;

procedure TweServerDataTransferService.FtpServer1Stop(Sender: TObject);
begin
 AddLog('! Ftp Server stopped', False);
 if not FServiceStoppedManually then
 begin
   AddLog('not FServiceStoppedManually, Restart', False);
   Sleep(5000); //
   HardRestart;
   //Restart;
 end;
end;

procedure TweServerDataTransferService.FtpServer1StorSessionClosed(Sender: TObject;
 Client: TFtpCtrlSocket; Data: TWSocket; AError: Word);
begin
 if AError = 0 then
   AddLog('File Received - ok')
 else
   AddLog('FtpServer1StorSessionClosed: error = ' + IntToStr(AError));
end;

procedure TweServerDataTransferService.FtpServer1ValidateGet(Sender: TObject;
 Client: TFtpCtrlSocket; var FilePath: TFtpString; var Allowed: Boolean);
begin
 Allowed := False;

 if (Pos(fnClientOptions2, FilePath) > 0) then
 begin
   AddLog('ClientOptions requested, path = ' + FweFolders.dirServerOptions + fnClientOptions2);
   FilePath := FweFolders.dirServerClientOptions + LowerCase(ExtractFileName(FilePath));
   Allowed := FileExists(FilePath);
 end;
end;

procedure TweServerDataTransferService.ServiceStart(Sender: TService; var Started: Boolean);
begin
               
   FtpServer1.Port := IntToStr(portServerClientsDT);
   FtpServer1.PasvPortRangeStart := portServerClientsDT2;
   FtpServer1.PasvPortRangeSize := portServerClientsDT2Size;
   
   FtpServer1.Start;  

end;

procedure TweServerDataTransferService.FtpServer1ValidateSize(Sender: TObject;
 Client: TFtpCtrlSocket; var FilePath: TFtpString; var Allowed: Boolean);
begin
 AddLog('FtpServer1ValidateSize - enter');
 AddLog('FilePath = ' + FilePath);

 Allowed := False;

 if (Pos(fnClientOptions2, FilePath) > 0) then
 begin
   Allowed := FileExists(FweFolders.dirServerClientOptions + ExtractFileName(FilePath));
 end;
end;

procedure TweServerDataTransferService.FtpServer1ValidatePut(Sender: TObject;
 Client: TFtpCtrlSocket; var FilePath: TFtpString; var Allowed: Boolean);
begin
 Allowed := False;

 if (Pos(prefPackage, FilePath) > 0) then
 begin
   Allowed := True;
   FilePath := FweFolders.dirServerLogs + ExtractFileName(FilePath);
 end;

end;

end.


Anatoly Podgoretsky   (2007-12-12 16:12:00) [18]

> DVM  (12.12.2007 15:47:21)  [21]

В общем это клонирование, но в Линуксе многое взяли из Виндоус


DVM   (2007-12-12 15:47:00) [19]


> Ну не получилось бы создать FTP сервер на 30000 одновременных
> подключений, только под стек потребуется 30 гб виртуальной
> памяти.

Кстати, а под Unix не знаете как реализуется подобное? Там ведь насколько я знаю вообще процесс сервера клонируется особым образом для каждого клиента.


Anatoly Podgoretsky   (2007-12-12 15:29:00) [20]

> MetalFan  (12.12.2007 14:59:18)  [18]

Система тоже не создает, это стандартный WinSock работает на сообщениях, а не потоках.
Ну не получилось бы создать FTP сервер на 30000 одновременных подключений, только под стек потребуется 30 гб виртуальной памяти.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо