| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C++ Builder > Indy 10 файл-сервер работает но както.... |
| Автор: ochelot 11.4.2013, 14:39 | ||
| Смысл кода в передаче файлов по сети от клиентов (в будущем с последующем доступом для клиентов (кому можно а кому нет)...) <client> <server> -> user <- user Ok -> sendfile <- ok; file name -> 11.mkv <- ok; file current -> данные <- next .... -> закончили <- ok -> exit <- exit ok. Т.е. в этом коде мы предполагаем что для обработки команд мы сначала отправляем user и входим в стадию обработки команд для user (в будущем проверка на права). И поле отправки мы остаемся и ожидаем следующую команду, только после exit вызываем Disconnect. Но не пойму по всем описаниям в методе void __fastcall TForm1::ServerExecute(TIdContext *AContext) мы не должны делать внутри цикл, для получения команд (типа пока нет Disconnect(a) Execute постоянно вызывается для клиента). Но если убрать цикл то сервер обрабатывает первую команду и на остальные уже не реагирует т.е. клиент отправил user получил ответ, после отправил exit и сервер ни как не отреагировал. Вопрос почему с циклом работает а без нет? ??? Можно ли систему команд и по другому реализовать без цикла :Server
|
| Автор: Avazart 12.4.2013, 15:05 | ||||
Ну а как бы почему должно работать? Для каждого клиента создается свой поток TIdThread наследованый от TThread, как я понимаю Execute() это ф-ция каждого потока. А значит и обработка должна вестись аналогично TThread по условию
|
| Автор: ochelot 12.4.2013, 15:40 | ||||||
Т.е. без цикла, при подключении клиента создается поток в котором вызывается Execute, выполняет его и по завершению закрывает поток (но не обрывает соединение (Disconnect)) и после Execute не вызывается, тем самым игнорируя последующие сообщения от клиента? Я думал что поток завершается когда происходит Disconnect... |
| Автор: Avazart 12.4.2013, 17:38 | ||
А что соединение не разрывается ? Последующие сообщения недоходят ибо надо заного установить соединение... |
| Автор: ochelot 12.4.2013, 19:33 | ||||
Ну во всяком случае событие TidTCPServer OnDisconnected не срабатывает если только вручную Disconected не вызвать. Следовательно он как бы не отключается. А вообще где можно узнать как эти механизмы работают? p.s. Читал Indy deep - так там как то поверхностно коснулись и то не 10 версии ИНДИ |
| Автор: Avazart 12.4.2013, 20:56 |
| Документация и Исходники ... Indy depf там только в общем ... Надо пробовать... попробую отпишусь... |
| Автор: Avazart 12.4.2013, 23:04 | ||
Смотрю в Indy in Depth стр 91 приводится пример и утверждается обратное что Execute() выполняется циклично, а соединение прерывается само если что-то не так, либо по команде:
http://s2.ipicture.ru/Gallery/Viewfull/23946450.html |
| Автор: ochelot 13.4.2013, 09:41 |
| Вот именно, вызывается OnExecute, проверяется соединение (CheckConnection) и снова вызывается OnExecute, и такой цикл для каждого клиента в отдельном потоке. В моем примере приходится вставлять в OnExecute еще цикл по условию В примере из книги OnExecute состоит из procedure TformMain.IdTCPServer1Execute(AThread: TIdPeerThread); а в Builder с indy 10 OnExecute состоит из void __fastcall TForm1::ServerExecute(TIdContext *AContext) отличия в параметрах... Я так понимаю в книге описывается indy 9 а мы используем 10 версию... говорят они кардинально отличаются... Могут ли у них и механизмы работы, что в диаграмме из книги работать по другому? p.s. Мне тут жена говорит "Ну если и так (как в примере) работает хорошо и как нужно, нафига лезть глубоко и пытаться что то поменять", но хочется же докопаться до истины |
| Автор: ochelot 13.4.2013, 10:15 | ||
Вот пример для indy 10 из официальной документации и вроде по описанию, диаграмма работы примерно такая же...
|
| Автор: Avazart 13.4.2013, 15:32 | ||
Да скорее всего у вас код не верный, читаете записываете неправильно ... |
| Автор: Avazart 13.4.2013, 17:57 | ||
| Вот мой пример сервера на скорую руку : ( без обработки команд, всегда отвечает клиенту "what?", добавил лог серверу но как-то криво вроде) Код C++
|
| Автор: ochelot 14.4.2013, 10:58 | ||||
Да, Вы правы... пробовал Ваш пример.. работает... Возникли вопросики 1. А для чего нужен TIdNotify? 2. Почему порт выдает при коннекте не 2013 (как порт сервера) а в логе пишется что то типа 127.0.0.1:2177 Recv 14.04.2013 11:51:22: USER 127.0.0.1:2177 Stat Disconnected. 0.0.0.0:0 Stat Disconnected. 127.0.0.1:2180 Stat Connected. 3. Как можно организовать проверку пользователя типа отправили user XXX и далее можно остальные команды и что по новой проверка только после Disconnect? 4.Какие потенциальные ошибки могут всплыть в моем примере при использовании множеством клиентов? |
| Автор: Avazart 14.4.2013, 16:36 |
| 1. Читайте комментарии в коде - для синхронизации... 2. Возможно потому что 2177,2180 это не порт, а возможно потому что порт настраивается как то не так. 3. В книге рекомендуется использовать не TIdTCPServer, а TIdCmdTCPServer он удобнее для команд ... 4. Я не знаю код код писал наугад ... |
| Автор: ochelot 15.4.2013, 10:42 |
| Спасибо за ответы А все таки если использовать OnExecute для верификации клиента, как теоретически организовать процедуру? При соединении клиент отправляет USER ivanov#123# пользователь и пароль. Сервер проверяет что такому пользователю разрешено выполнять такие то команды (например TIME). И получается есть список команд: DATE - Разрешено только клиенту ivanov TIME - Разрешено только клиенту petrov LIST - Разрешено всем USER - Разрешено всем Единственное мне приходит в голову сохранять данные где то о клиенте при прохождении проверки USER xxx , при каждом вызове OnExecute проверять проходил ли пользователь проверку и проверять что ему можно а что нет, при OnDisconnect забываем данные о клиенте. |
| Автор: Avazart 15.4.2013, 16:26 | ||||
Лучше
Тогда не придется парсить и в коде можно использовать switch/case
Ну да, а еще видимо нужна будет БД содержащая список пользователей их права, - тут нужно будет обеспечить потокобезопасность. |
| Автор: ochelot 17.4.2013, 10:09 | ||||||||
А вот как узнать какой клиент отправил запрос? Например если ivanov прошел проверку, мы сохранили (вопрос еще как сохранить для потока где обрабатывается только наш клиент), при следующем вызове OnExecute смотрим что проходил и выполняем команду. Просто потоков с клиентами может быть много и тех же OnExecute будут вызываться множество, а вот вопрос как узнать кто есть кто, вопрос...
|
| Автор: Avazart 17.4.2013, 16:00 | ||
У TIdContext есть свойство
Вот думаю оно и предназначено для хранения данных о каждом соединении. |
| Автор: fish9370 29.4.2013, 20:31 |
| я боюсь быть забросанным гнилыми помидорами, но вам не кажется, что все можно сделать намного проще с помощью обычных сишных функций? |
| Автор: Avazart 30.4.2013, 00:37 | ||
А ты попробуй, во что превратится твой код Си-шный код ? Как его будет удобно поддерживать ? Что может проще чем кинуть пару компонентов ? В большинстве случаем легче один разобраться как использовать уже написанное, чем городить свой одноколёсный |
| Автор: Alca 30.4.2013, 09:19 | ||
А потом думать, почему это работает, но как-то криво |
| Автор: Avazart 30.4.2013, 18:33 | ||||||
Опыт показывает что не работает не из-за Indy, а из-за кривых рук... Читать доку надо, смотреть в исходники ...
Земля пухом такому коду ... ( ну хотя бы потому что он си )
Наверное в твоем коде только ты разбираешься ... А выигрыш в скорости обычно копеечный. |
| Автор: Alca 30.4.2013, 18:41 | ||
В моем случае это было наоборот. |
| Автор: Avazart 30.4.2013, 18:46 | ||||
Ну так не нашли ведь почему ? |
| Автор: Alca 30.4.2013, 21:14 | ||
Я нашел, но потом пришлось самому пересобирать 10-ых индейцев. А это еще тот геморой. |
| Автор: Avazart 1.5.2013, 02:33 | ||
А можно поинтересоваться в чем проблема была ? |
| Автор: fish9370 1.5.2013, 19:56 |
ха-ха.. удачи.. |
| Автор: Alca 1.5.2013, 21:32 | ||
SMTP server, в размере буфера для строки, пришлось увеличивать. |
| Автор: Avazart 1.5.2013, 22:01 |
| Как я помню размер буферов Indy настраиваем, по крайней мере не думаю что перекомпиляция так была необходима Ну само собой компонент та тоже не простой ... И тебе не хворать... |
| Автор: Alca 2.5.2013, 10:18 | ||||||
Это как Добавлено через 7 минут Вот тема: http://forum.vingrad.ru/forum/topic-269219.html Вот исходник: http://trac.xananews.techtips.com.br/browser/trunk/components/thirdparty/Indy10/Core/IdIOHandler.pas
Ты прав, там есть такое свойство Добавлено через 7 минут и 46 секунд
|
| Автор: Avazart 4.5.2013, 00:21 | ||
Кстати а что в компоненте мах длина строки была изначально меньше чем указана в RFC ?
|
| Автор: Alca 4.5.2013, 00:57 | ||
http://trac.xananews.techtips.com.br/browser/trunk/components/thirdparty/Indy10/Core/IdIOHandler.pas
|
| Автор: Avazart 4.5.2013, 14:29 |
| Я к тому что изначально менять длину было неправильным подходом, так как следовало полагаться на RFC 1024 > 988 |