|
|
|
TServerSocket и TService
|
|||
|---|---|---|---|
|
#18+
oklalexа в лог себе вывожу перед этимМожет, при записи в лог какие проблемы. Может, out of memory. Может компонент глючит. Я никогда не использовал TServerSocket в неблокирующем режиме - только в stThreadBlocking, но там работал вроде норм. Хотя потом перешел на чистое апи и написал свой TServerSocket. Что-то раздражало и чего-то не хватало. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.10.2019, 12:12 |
|
||
|
TServerSocket и TService
|
|||
|---|---|---|---|
|
#18+
oklalexПока вижу только два варианта - 1. Отказаться от службы и юзать десктопный вариант. Прям совсем не хотелось бы, ибо десктоп на сервере зло (нужен логин на сервер), а служба очень удобная вещь, сама запускается, работает в фоне, ресурсов минимум, не требует входа в систему - идеальный вариант для такого сервера. 2. Отказаться от TServerSocket и использовать что-то иное. В общем-то, несложно настроить запуск "десктопа", чтобы запускался до того, как кто-то залогинится. Мы так жили одно время, настраивали в диспетчере задач запуск, и все было нормально, только от админа требовалось, чтобы он настроил. А еще сделали костыль. Отчего-то переделка сервера-десктопа в сервис сразу не завелась, и вот сделали тяп-ляп. Лончер-сервис, который запускает десктоп-приложение. И следит за тем, что приложение еще живо и перезапускает его, если что. Потом мы, конечно, от костыля избавимся, и переделаем десктоп в нормальный сервис. Когда все дела переделаем, да-да-да. А пока все работает. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.10.2019, 12:53 |
|
||
|
TServerSocket и TService
|
|||
|---|---|---|---|
|
#18+
oklalex, а сервер что то пишет в ответ клиенту? судя по коду, пока не напишет, не пойдет дальше читать. может проблема в том что клиент не ждет данных и не вычитывает их из буфера? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.10.2019, 13:03 |
|
||
|
TServerSocket и TService
|
|||
|---|---|---|---|
|
#18+
YuRockoklalexа в лог себе вывожу перед этимМожет, при записи в лог какие проблемы. Может, out of memory. Может компонент глючит. Я никогда не использовал TServerSocket в неблокирующем режиме - только в stThreadBlocking, но там работал вроде норм. Хотя потом перешел на чистое апи и написал свой TServerSocket. Что-то раздражало и чего-то не хватало. Тоже не использую. Работаю с Indy, там только блокирующий режим. Сотни постоянных подключений, работает годами, глюков не наблюдал. Если делать 32-разрядную прогу, то упрешься в лимит подключений из-за виртуальной памяти (особенно если 64-битная винда). Для 64-разрядной проги Indy будет без проблем держать тысячи подключений. ОЗУ при этом расходуется не более 64 КБ на подключение. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.10.2019, 13:04 |
|
||
|
TServerSocket и TService
|
|||
|---|---|---|---|
|
#18+
Zelius, всмысле, пока клиент не прочтет написанное ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.10.2019, 13:04 |
|
||
|
TServerSocket и TService
|
|||
|---|---|---|---|
|
#18+
DmSerЕсли делать 32-разрядную прогу, то упрешься в лимит подключений из-за виртуальной памяти (особенно если 64-битная винда). Для 64-разрядной проги Indy будет без проблем держать тысячи подключений. ОЗУ при этом расходуется не более 64 КБ на подключение.Там проблема (не знаю, есть ли она в Indy), что потоку-клиенту нельзя указать размер стека (вообще в стандартном TThread), и он указывается по-умолчанию (0, т.е. размер стека 1-го потока процесса - а это мегабайт(ы)). А для таких потоков зачастую размер стека нужен ничтожный. Поэтому в своем сервере я сделал старт клиентских потоков через BeginThread. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.10.2019, 13:13 |
|
||
|
TServerSocket и TService
|
|||
|---|---|---|---|
|
#18+
YuRockХотя потом перешел на чистое апи и написал свой TServerSocket. Что-то раздражало и чего-то не хваталоу меня на базе TServerSocket и TSocketDispatcher сервисы работают (правда клиентов сотнями не бывает), но столько всего исправить и взломать пришлось что правильнее было свою иерархию именно с нуля или как можно ниже воротить чем столько крэкеров задействовать ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.10.2019, 13:18 |
|
||
|
TServerSocket и TService
|
|||
|---|---|---|---|
|
#18+
YuRockТам проблема (не знаю, есть ли она в Indy), что потоку-клиенту нельзя указать размер стека (вообще в стандартном TThread), и он указывается по-умолчанию (0, т.е. размер стека 1-го потока процесса - а это мегабайт(ы)). А для таких потоков зачастую размер стека нужен ничтожныйаналогично TRemoteExecutionThread от своего TVThread к-й задает произвольный размер стэка ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.10.2019, 13:21 |
|
||
|
TServerSocket и TService
|
|||
|---|---|---|---|
|
#18+
DmSerYuRockпропущено... Может, при записи в лог какие проблемы. Может, out of memory. Может компонент глючит. Я никогда не использовал TServerSocket в неблокирующем режиме - только в stThreadBlocking, но там работал вроде норм. Хотя потом перешел на чистое апи и написал свой TServerSocket. Что-то раздражало и чего-то не хватало. Тоже не использую. Работаю с Indy, там только блокирующий режим. Сотни постоянных подключений, работает годами, глюков не наблюдал. Если делать 32-разрядную прогу, то упрешься в лимит подключений из-за виртуальной памяти (особенно если 64-битная винда). Для 64-разрядной проги Indy будет без проблем держать тысячи подключений. ОЗУ при этом расходуется не более 64 КБ на подключение. Вот, это отдельная часть этой оперы. Windows 10 Pro и все приложения строго 64-битные, написаны на Delphi 10.3, как и многое другое. Сам работаю с Indy и все гладко, но есть один момент - там и клиенты, и сервер написаны мной, ReadStream/WriteStream и все дела. TIdTCPClient/Server сам пишет в сообщение размерность данных, поток любого размера прекрасно передается по сети. А с этим сервером проблема. Там многое разработано не мной, там контроллеры, там старые программы, написанные еще на Visual Studio 5 на MFC и многие другие прелести жизни. Они не пишут в протокол размерность данных. Как в этом случае правильно работать с IdTCPServer. Он вызывает событие OnExecute, потом надо как-то принять весь входной буфер, не зная его размера, ибо сообщения более 1 КБ "по дороге" фрагментируются . Затем, надо как-то иметь доступ к этим подключениям, чтобы в любой момент отправить им в активный сокет данные, найдя этот сокет по его Handle. Если все это можно запилить на IdTCPServer, подскажите, как. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.10.2019, 13:23 |
|
||
|
TServerSocket и TService
|
|||
|---|---|---|---|
|
#18+
oklalex надо как-то принять весь входной буфер, не зная его размера, ибо сообщения более 1 КБ "по дороге" фрагментируются Фрагментироваться могут любые буффера. Принимать, собирая и разбивая на пакеты, необходимо через свой протокол (или чужой, предназначенный для такого). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.10.2019, 13:27 |
|
||
|
TServerSocket и TService
|
|||
|---|---|---|---|
|
#18+
YuRockoklalex надо как-то принять весь входной буфер, не зная его размера, ибо сообщения более 1 КБ "по дороге" фрагментируются Фрагментироваться могут любые буффера. Принимать, собирая и разбивая на пакеты, необходимо через свой протокол (или чужой, предназначенный для такого). Вопрос уже был конкретно по Indy адресован человеку ) TIdTCPServer заточен под прием данных, зная их размерность. В TServerSocket есть событие OnClientRead - оно срабатывает подряд для одного сокета до тех пор, пока весь буфер не примет. Код: pascal 1. Поэтому получается "собрать" сообщение и привязать его к хэндлу сокета, ибо сокет нам передается в параметрах. А дальше парсинг и соединение висит, пока не придет следующий пакет. О размерности данных я понятия не имею - просто принимаю весь входной буфер. Вопрос в том, как это сделать на TIdTCPServer... если переходить на него ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.10.2019, 13:34 |
|
||
|
TServerSocket и TService
|
|||
|---|---|---|---|
|
#18+
Zelius, Сервер пишет, клиент ловит и отмечает, что принято. Там логика четкая. Дебажить службы умею, только вот проявляется это уже на реальном сервере, где счет на сотни и тысячи подключений, там не отдебажить никак и ставить туда не хотелось бы ничего ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.10.2019, 13:47 |
|
||
|
TServerSocket и TService
|
|||
|---|---|---|---|
|
#18+
oklalex, тогда только логгирование, включая потроха TServerSocket, затянуть в проект, напихать во все места... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.10.2019, 14:04 |
|
||
|
TServerSocket и TService
|
|||
|---|---|---|---|
|
#18+
Zeliusoklalex, тогда только логирование, включая потроха TServerSocket, затянуть в проект, напихать во все места... И так перетрес его весь, да и в десктоп-варианте он работает ведь. Думаю, проще перейти с него на что-нибудь другое, попробовать TIdTCPServer, но тогда выше написанное мной в силе ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.10.2019, 14:08 |
|
||
|
TServerSocket и TService
|
|||
|---|---|---|---|
|
#18+
oklalexZeliusoklalex, тогда только логирование, включая потроха TServerSocket, затянуть в проект, напихать во все места... И так перетрес его весь, да и в десктоп-варианте он работает ведь. Думаю, проще перейти с него на что-нибудь другое, попробовать TIdTCPServer, но тогда выше написанное мной в силе Indy кстати тоже в свое время перевернул вверх дном исходник, кое-что допилил под себя. Речь о версии 10. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.10.2019, 14:09 |
|
||
|
TServerSocket и TService
|
|||
|---|---|---|---|
|
#18+
oklalexИ так перетрес его весь, да и в десктоп-варианте он работает ведь.Значит, логируется не всё, что нужно, раз не можешь найти, где зависает. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.10.2019, 14:18 |
|
||
|
TServerSocket и TService
|
|||
|---|---|---|---|
|
#18+
YuRock, Это да, буду сейчас дальше копать, но про переход на TIdTCPServer тоже было бы интересно сделать ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.10.2019, 14:21 |
|
||
|
TServerSocket и TService
|
|||
|---|---|---|---|
|
#18+
oklalexDmSerпропущено... Тоже не использую. Работаю с Indy, там только блокирующий режим. Сотни постоянных подключений, работает годами, глюков не наблюдал. Если делать 32-разрядную прогу, то упрешься в лимит подключений из-за виртуальной памяти (особенно если 64-битная винда). Для 64-разрядной проги Indy будет без проблем держать тысячи подключений. ОЗУ при этом расходуется не более 64 КБ на подключение. Вот, это отдельная часть этой оперы. Windows 10 Pro и все приложения строго 64-битные, написаны на Delphi 10.3, как и многое другое. Сам работаю с Indy и все гладко, но есть один момент - там и клиенты, и сервер написаны мной, ReadStream/WriteStream и все дела. TIdTCPClient/Server сам пишет в сообщение размерность данных, поток любого размера прекрасно передается по сети. А с этим сервером проблема. Там многое разработано не мной, там контроллеры, там старые программы, написанные еще на Visual Studio 5 на MFC и многие другие прелести жизни. Они не пишут в протокол размерность данных. Как в этом случае правильно работать с IdTCPServer. Он вызывает событие OnExecute, потом надо как-то принять весь входной буфер, не зная его размера, ибо сообщения более 1 КБ "по дороге" фрагментируются . Затем, надо как-то иметь доступ к этим подключениям, чтобы в любой момент отправить им в активный сокет данные, найдя этот сокет по его Handle. Если все это можно запилить на IdTCPServer, подскажите, как. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.10.2019, 14:22 |
|
||
|
TServerSocket и TService
|
|||
|---|---|---|---|
|
#18+
oklalexОни не пишут в протокол размерность данных. Как в этом случае правильно работать с IdTCPServer. Он вызывает событие OnExecute, потом надо как-то принять весь входной буфер, не зная его размера Если в данных нет длины или признака окончания - никак. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.10.2019, 14:46 |
|
||
|
TServerSocket и TService
|
|||
|---|---|---|---|
|
#18+
oklalex, если вдруг решишь переписывать на другой транспорт - посмотри сюда. И синхронно, и асинхронно. Атомарность (блок либо пришел, либо нет), очереди сообщений "искаропки", автоматическое восстановление соединения, отличная документация, другие печеньки. Мы используем - все как часы работает. Одна dll и адаптер .h -> .pas. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.10.2019, 15:05 |
|
||
|
TServerSocket и TService
|
|||
|---|---|---|---|
|
#18+
oklalexZeliusoklalex, тогда только логирование, включая потроха TServerSocket, затянуть в проект, напихать во все места... И так перетрес его весь, да и в десктоп-варианте он работает ведь. Думаю, проще перейти с него на что-нибудь другое, попробовать TIdTCPServer, но тогда выше написанное мной в силе Я для этого использую конечный автомат. В ход идут методы: ClientSocket.Connection.Socket.InputBuffer.Size ClientSocket.Connection.Socket.CheckForDataOnSource(50) ClientSocket.Connection.Socket.ReadByte() ClientSocket.Connection.Socket.InputBuffer.Extract() Нужно также учитывать, что перед вызовом ClientSocket.Connection.Disconnect необходимо проверить ClientSocket.Connection.Socket.InputBuffer.Size и считать все имеющиеся байты. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.10.2019, 17:28 |
|
||
|
TServerSocket и TService
|
|||
|---|---|---|---|
|
#18+
DmSeroklalexпропущено... И так перетрес его весь, да и в десктоп-варианте он работает ведь. Думаю, проще перейти с него на что-нибудь другое, попробовать TIdTCPServer, но тогда выше написанное мной в силе Я для этого использую конечный автомат. В ход идут методы: ClientSocket.Connection.Socket.InputBuffer.Size ClientSocket.Connection.Socket.CheckForDataOnSource(50) ClientSocket.Connection.Socket.ReadByte() ClientSocket.Connection.Socket.InputBuffer.Extract() Нужно также учитывать, что перед вызовом ClientSocket.Connection.Disconnect необходимо проверить ClientSocket.Connection.Socket.InputBuffer.Size и считать все имеющиеся байты. Друзья, всем спасибо за ответы, мнения, комментарии, уделенное время! С TServerSocket изрядно покопался, там достойно отдельной темы )) но ничего так не получилось )) Решил переехать пока на Indy, ибо их неплохо знаю и с ними много приходилось работать. Итак, имеем TIdTCPServer: Код: pascal 1. 2. 3. 4. 5. 6. При отправке сообщения на него оно приходит в OnExecute(), как и должно быть, затем я его там ловлю, как и советовал DmSer - примерно так: Код: pascal 1. 2. 3. 4. 5. 6. 7. Затем, специально подключив GPRS-канал, делаю передачу крупного (> 1 КБ) сообщения, чтобы вызвать фрагментацию сообщения. В этом случае сообщение снова приходит частями, для каждой из которых вызывается OnExecute() до тех пор, пока входной буфер не пуст. И тут есть очень сильная хотелка - как бы так "собрать" это сообщение в первом вызове OnExecute(), зациклив проверку буфера? Ибо здесь все, что делается в OnExecute(), выполняется в отдельном потоке и крайне не хотелось бы заморачиваться внешними глобальными списками/массивами и "сборкой" полного сообщения. Хотелось бы - чтобы все действия по приему и обработке одного сообщения "не покидали" этого отдельного потока. Пробовал сделать нечто такое (код очень грубый, экспериментально, не ругайте): Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. Отрабатывает, но при этом OnExecute() почему-то продолжает постоянно вызываться, хотя входной буфер пуст (разумеется, грузит ЦП и прочее). Само соединение при этом активно и должно таковым оставаться сколь угодно долго. Таким образом, возникает первый вопрос - как правильно реализовать эту простую логику? Длины входного сообщения я не знаю. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.10.2019, 14:37 |
|
||
|
TServerSocket и TService
|
|||
|---|---|---|---|
|
#18+
Дополню - OnExecute() всегда начинает вызываться постоянно, пока висит подключение. Хотя бы этого как-то можно избежать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.10.2019, 16:03 |
|
||
|
|

start [/forum/topic.php?fid=58&msg=39869909&tid=2038959]: |
0ms |
get settings: |
9ms |
get forum list: |
17ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
150ms |
get topic data: |
10ms |
get forum data: |
3ms |
get page messages: |
78ms |
get tp. blocked users: |
1ms |
| others: | 240ms |
| total: | 514ms |

| 0 / 0 |
