powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / TServerSocket и TService
55 сообщений из 55, показаны все 3 страниц
TServerSocket и TService
    #39869661
oklalex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Доброго времени, уважаемые форумчане!
Прошу помощи в следующем. Имеем "отладочное" приложение, которое содержит TServerSocket, работающий в неблокирующем режиме (stNonBlocking) и принимающий данные от кучи разных устройств/локальных клиентских программ и прочее. Все отлично работает, срабатывает событие OnClientRead(), выполняю обработку и, при необходимости, отправку данных при помощи SendText(). В случае, если данные были разбиты на части во время их передачи, OnClientRead() вызывается для каждой части по порядку и проблем тоже нет.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
// при создании формы (службы)
FServerSocket := TServerSocket.Create(nil);
FServerSocket.OnClientError := OnError;
FServerSocket.OnClientRead := OnRead;
FServerSocket.OnClientDisconnect := OnDisconnect;

// при разрушении формы (службы)
for Index := 0 to FServerSocket.Socket.ActiveConnections - 1 do
  FServerSocket.Socket.Connections[Index].Close;
FServerSocket.Close;


Затем, все это дело я оформил как службу - штатный TService. И появилась такая проблема - все работает примерно в течение часа, затем перестает работать. Служба запущена всегда, остановок и исключений нет. Сделал свой собственный простой и примитивный лог - вижу, что после определенного количества подключений (около 100 активных sockets) перестает срабатывать событие OnClientRead(). То есть, клиент подключается, подключение проходит, но событие уже не срабатывает. При перезапуске службы, разумеется, все начинает работать, опять-таки до поры до времени. Если кто сталкивался с чем-то подобным, пуду премного признателен.
Может быть, дело в том, что нельзя использовать stNonBlocking внутри службы? Программа была идеально отлажена именно в этом режиме работы сервера.
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869670
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сомнительно что-то. Если в режиме десктопа работает, то режиме службы должно. Может в каких-то ситуациях окна открываются, ShowMessage например?
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869672
oklalex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
DmSer,
В том и дело, что нет никаких ShowMessage(), как будто бы есть какое-то ограничение на количество подключений (что-то типа ThreadCacheSize - но это для блокирующего режима и работы с потоками, а здесь все в главном потоке, ибо обработка очень быстрая).
Пока поставил в таймере такой "костыль" с интервалом на 1 час (3600000 мс).

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
try
  for Index := 0 to FServerSocket.Socket.ActiveConnections - 1 do
    FServerSocket.Socket.Connections[Index].Close;
  FServerSocket.Close;
finally
  if not FServerSocket.Active then
    FServerSocket.Open;
end;


Пока все это работает, но это не дело совсем, конечно...
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869676
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
автора здесь все в главном потоке, ибо обработка очень быстрая.

Видимо у Вас где-то происходит зависание в основном потоке. Может дедлок? TService как-то взаимодейстует с TServerSocket?
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869683
oklalex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
DmSer,
Теоретически не должно быть зависаний, ибо действующие подключения еще некоторое время работают, потом вообще умирает все. Кстати, вышеприведенный "костыль" не помог - все равно перестает срабатывать событие, я это вижу по своему кустарному логу и по факту того, что ответ SendText() перестает приходить через некоторое время (отправляю при помощи Packet Sender - эмулирую сообщение клиента). А каким образом TService может взаимодействовать с TServerSocket? Только запуск, остановка, обработка событий от TServerSocket.
Экземпляр TServerSocket создаю динамически в RunTime, ибо убрали их давно из палитры компонентов, так удобнее.
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869685
oklalex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
DmSer,
Deadlock тоже не должно быть, ибо база работает на чтение, операция записи крайне редкая - и, думаю, это было бы хорошо видно еще в десктопном варианте, но там такого и близко не было
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869687
Zelius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
oklalex,

имхо, либо в локе висит, тогда можно посмотреть каким-нибудь ProcessExplorer, так ли это
либо сокеты кончились, можно посмотреть тем же ProcessExplorer или netstat'ом
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869693
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ставлю на исключение, которое что-то повесило.
Хотя, конечно, может быть и лок из-за какого-нибудь synchronize.
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869696
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockСтавлю на исключение, которое что-то повесило.


Кстати да, если в службе возникнет исключения, то, если оно не обработано в try..except, то будет открыто окно с ошибкой ShowMessage, которое в режиме службы никто не увидит.
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869703
oklalex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
DmSer,
try... except все на месте, но все равно сейчас пытаюсь проверить на зависание/срабатывание Exception, может, где что упустил. В десктопе, правда, никаких исключений не выпадало, все обрабатывается.
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869787
oklalex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
DmSer,
Зависание маловероятно, ибо поставил таймер и он работает в главном потоке, вижу по логам, да и действующие подключения еще живут какое-то время и работает обмен данными, что видно при помощи сниффера и при отправке эмуляции пакета и получением ответа программой Packet Sender. Исключений тоже нет - проверил, да и не было в десктопе - там все чисто по исключениям, расставлены все try ... except/finally.
А что значит - кончились сокеты? В декстопе же не кончались, я там тысячи подключений делал и работало идеально. Здесь же после 100 - 150 активных подключений уже все падает. Причем обнаружил такую вещь, которая совсем лишила меня понимания - иногда после "зависания" снова начинает работать, будто переполняется/высвобождается какой-то глобальный ресурс. В десктопе ничего подобного не было.
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869792
Zelius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
oklalex,

посмотри SO_REUSEADDR
подключения постоянные или переподключается постоянно?
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869794
Zelius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
oklalex,

похоже ошибся опцией, сорри
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869795
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пальцем в небо: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\EnableConnectionRateLimiting - должно быть 0.
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869802
oklalex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Пока вижу только два варианта -
1. Отказаться от службы и юзать десктопный вариант. Прям совсем не хотелось бы, ибо десктоп на сервере зло (нужен логин на сервер), а служба очень удобная вещь, сама запускается, работает в фоне, ресурсов минимум, не требует входа в систему - идеальный вариант для такого сервера.
2. Отказаться от TServerSocket и использовать что-то иное.
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869805
oklalex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
wadman,
Сейчас гляну...
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869814
oklalex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Zelius,
Подключения постоянные - живут столько, сколько позволит сеть и условия. Там, где GPRS - рвется немного чаще, так как, по моему, сотовые операторы как-то регламентируют время жизни сессии. Там, где локалка - могут и сутками висеть
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869818
Zelius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
oklalex,

посмотри netstat все же, сколько там висит соединений и в каком состоянии... может залипают соединения
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869823
oklalex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
wadmanПальцем в небо: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\EnableConnectionRateLimiting - должно быть 0.
Вовсе нет такого параметра в этой ветви...
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869827
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
oklalexЗависание маловероятно, ибо поставил таймер и он работает в главном потоке, вижу по логамЗначит - точно MessageBox (или какое другое модальное окно) висит.
Он не мешает отрабатывать таймеру.
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869830
Zelius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
oklalex,

https://docs.microsoft.com/en-us/sysinternals/downloads/process-explorer

там у процесса есть вкладка TCP/IP, есть список потоков, по каждому можно стек посмотреть, хоть и без дельфи кода, может натолкноеит на мысль
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869832
oklalex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Zeliusoklalex,
посмотри netstat все же, сколько там висит соединений и в каком состоянии... может залипают соединения
Соединений там всегда очень много - некоторые из тех, что по GPRS, могут находиться в TIME_WAIT, это нормально для них в целом, потом, как я понимаю, они умирают и клиент переподключается. Те, которые по локальной сети или по LTE, там у всех ESTABLISHED всегда.
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869833
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
oklalexDmSer,
try... except все на месте, но все равно сейчас пытаюсь проверить на зависание/срабатывание Exception, может, где что упустил. В десктопе, правда, никаких исключений не выпадало, все обрабатывается.В "десктопе" были совсем другие права.
У службы, например, нет прав на сетевые шары, которые были у твоего "десктопа". И многое еще отличается. Ты можешь не видеть каких-то окон, объектов...
Может, в этом причина.
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869836
oklalex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
YuRockoklalexЗависание маловероятно, ибо поставил таймер и он работает в главном потоке, вижу по логамЗначит - точно MessageBox (или какое другое модальное окно) висит.
Он не мешает отрабатывать таймеру.
Если бы все было так просто ) Я этот код уже вверх дном перевернул, в десктопе запускал по-разному... Попробую еще поискать. Может, сам TServerSocket что выдает, но я его сообщения подавляю (ErrorCode задаю 0), а в лог себе вывожу перед этим
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869844
oklalex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
YuRockoklalexDmSer,
try... except все на месте, но все равно сейчас пытаюсь проверить на зависание/срабатывание Exception, может, где что упустил. В десктопе, правда, никаких исключений не выпадало, все обрабатывается.В "десктопе" были совсем другие права.
У службы, например, нет прав на сетевые шары, которые были у твоего "десктопа". И многое еще отличается. Ты можешь не видеть каких-то окон, объектов...
Может, в этом причина.
Вот про это думал тоже и не раз . Службу пробовал запускать, как от системной учетной записи, так и как сетевую службу, так и от имени администратора (задав логин и пароль в настройках службы). Ничего не помогает. Десктоп при этом запускал с обычными правами, как калькулятор. Да и служба там простая - парсит данные и сохраняет на отдельный локальный диск, никаких прав особых ей не требуется.
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869849
Zelius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869851
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
oklalexа в лог себе вывожу перед этимМожет, при записи в лог какие проблемы.
Может, out of memory.
Может компонент глючит.
Я никогда не использовал TServerSocket в неблокирующем режиме - только в stThreadBlocking, но там работал вроде норм.
Хотя потом перешел на чистое апи и написал свой TServerSocket. Что-то раздражало и чего-то не хватало.
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869879
ёёёёё
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
oklalexПока вижу только два варианта -
1. Отказаться от службы и юзать десктопный вариант. Прям совсем не хотелось бы, ибо десктоп на сервере зло (нужен логин на сервер), а служба очень удобная вещь, сама запускается, работает в фоне, ресурсов минимум, не требует входа в систему - идеальный вариант для такого сервера.
2. Отказаться от TServerSocket и использовать что-то иное.
В общем-то, несложно настроить запуск "десктопа", чтобы запускался до того, как кто-то залогинится. Мы так жили одно время, настраивали в диспетчере задач запуск, и все было нормально, только от админа требовалось, чтобы он настроил.

А еще сделали костыль. Отчего-то переделка сервера-десктопа в сервис сразу не завелась, и вот сделали тяп-ляп. Лончер-сервис, который запускает десктоп-приложение. И следит за тем, что приложение еще живо и перезапускает его, если что. Потом мы, конечно, от костыля избавимся, и переделаем десктоп в нормальный сервис. Когда все дела переделаем, да-да-да. А пока все работает.
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869890
Zelius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
oklalex,

а сервер что то пишет в ответ клиенту? судя по коду, пока не напишет, не пойдет дальше читать. может проблема в том что клиент не ждет данных и не вычитывает их из буфера?
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869891
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockoklalexа в лог себе вывожу перед этимМожет, при записи в лог какие проблемы.
Может, out of memory.
Может компонент глючит.
Я никогда не использовал TServerSocket в неблокирующем режиме - только в stThreadBlocking, но там работал вроде норм.
Хотя потом перешел на чистое апи и написал свой TServerSocket. Что-то раздражало и чего-то не хватало.

Тоже не использую. Работаю с Indy, там только блокирующий режим. Сотни постоянных подключений, работает годами, глюков не наблюдал. Если делать 32-разрядную прогу, то упрешься в лимит подключений из-за виртуальной памяти (особенно если 64-битная винда). Для 64-разрядной проги Indy будет без проблем держать тысячи подключений. ОЗУ при этом расходуется не более 64 КБ на подключение.
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869894
Zelius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zelius,

всмысле, пока клиент не прочтет написанное
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869904
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DmSerЕсли делать 32-разрядную прогу, то упрешься в лимит подключений из-за виртуальной памяти (особенно если 64-битная винда). Для 64-разрядной проги Indy будет без проблем держать тысячи подключений. ОЗУ при этом расходуется не более 64 КБ на подключение.Там проблема (не знаю, есть ли она в Indy), что потоку-клиенту нельзя указать размер стека (вообще в стандартном TThread), и он указывается по-умолчанию (0, т.е. размер стека 1-го потока процесса - а это мегабайт(ы)).
А для таких потоков зачастую размер стека нужен ничтожный.
Поэтому в своем сервере я сделал старт клиентских потоков через BeginThread.
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869909
vavan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockХотя потом перешел на чистое апи и написал свой TServerSocket. Что-то раздражало и чего-то не хваталоу меня на базе TServerSocket и TSocketDispatcher сервисы работают (правда клиентов сотнями не бывает), но столько всего исправить и взломать пришлось что правильнее было свою иерархию именно с нуля или как можно ниже воротить чем столько крэкеров задействовать
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869911
vavan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockТам проблема (не знаю, есть ли она в Indy), что потоку-клиенту нельзя указать размер стека (вообще в стандартном TThread), и он указывается по-умолчанию (0, т.е. размер стека 1-го потока процесса - а это мегабайт(ы)).
А для таких потоков зачастую размер стека нужен ничтожныйаналогично TRemoteExecutionThread от своего TVThread к-й задает произвольный размер стэка
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869912
oklalex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
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, подскажите, как.
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869915
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
oklalex надо как-то принять весь входной буфер, не зная его размера, ибо сообщения более 1 КБ "по дороге" фрагментируются Фрагментироваться могут любые буффера.
Принимать, собирая и разбивая на пакеты, необходимо через свой протокол (или чужой, предназначенный для такого).
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869921
oklalex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
YuRockoklalex надо как-то принять весь входной буфер, не зная его размера, ибо сообщения более 1 КБ "по дороге" фрагментируются Фрагментироваться могут любые буффера.
Принимать, собирая и разбивая на пакеты, необходимо через свой протокол (или чужой, предназначенный для такого).
Вопрос уже был конкретно по Indy адресован человеку )
TIdTCPServer заточен под прием данных, зная их размерность.
В TServerSocket есть событие OnClientRead - оно срабатывает подряд для одного сокета до тех пор, пока весь буфер не примет.

Код: pascal
1.
procedure OnRead(Sender: TObject; Socket: TCustomWinSocket);


Поэтому получается "собрать" сообщение и привязать его к хэндлу сокета, ибо сокет нам передается в параметрах. А дальше парсинг и соединение висит, пока не придет следующий пакет. О размерности данных я понятия не имею - просто принимаю весь входной буфер. Вопрос в том, как это сделать на TIdTCPServer... если переходить на него
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869926
oklalex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Zelius,
Сервер пишет, клиент ловит и отмечает, что принято. Там логика четкая. Дебажить службы умею, только вот проявляется это уже на реальном сервере, где счет на сотни и тысячи подключений, там не отдебажить никак и ставить туда не хотелось бы ничего
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869944
Zelius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
oklalex,

тогда только логгирование, включая потроха TServerSocket, затянуть в проект, напихать во все места...
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869947
oklalex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Zeliusoklalex,
тогда только логирование, включая потроха TServerSocket, затянуть в проект, напихать во все места...
И так перетрес его весь, да и в десктоп-варианте он работает ведь. Думаю, проще перейти с него на что-нибудь другое, попробовать TIdTCPServer, но тогда выше написанное мной в силе
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869949
oklalex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
oklalexZeliusoklalex,
тогда только логирование, включая потроха TServerSocket, затянуть в проект, напихать во все места...
И так перетрес его весь, да и в десктоп-варианте он работает ведь. Думаю, проще перейти с него на что-нибудь другое, попробовать TIdTCPServer, но тогда выше написанное мной в силе
Indy кстати тоже в свое время перевернул вверх дном исходник, кое-что допилил под себя. Речь о версии 10.
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869958
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
oklalexИ так перетрес его весь, да и в десктоп-варианте он работает ведь.Значит, логируется не всё, что нужно, раз не можешь найти, где зависает.
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869962
oklalex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
YuRock,
Это да, буду сейчас дальше копать, но про переход на TIdTCPServer тоже было бы интересно сделать
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869963
oklalex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
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, подскажите, как.
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39869992
ёёёёё
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
oklalexОни не пишут в протокол размерность данных. Как в этом случае правильно работать с IdTCPServer. Он вызывает событие OnExecute, потом надо как-то принять весь входной буфер, не зная его размера
Если в данных нет длины или признака окончания - никак.
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39870006
ёёёёё
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
oklalex,

если вдруг решишь переписывать на другой транспорт - посмотри сюда.
И синхронно, и асинхронно. Атомарность (блок либо пришел, либо нет), очереди сообщений "искаропки", автоматическое восстановление соединения, отличная документация, другие печеньки.
Мы используем - все как часы работает. Одна dll и адаптер .h -> .pas.
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39870132
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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 и считать все имеющиеся байты.
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39871165
oklalex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
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.
FIdTCPServer := TIdTCPServer.Create(nil);
FIdTCPServer.OnExecute := OnExecute;
FIdTCPServer.OnException := OnException;
FIdTCPServer.OnDisconnect := OnDisconnect;
FIdTCPServer.DefaultPort := DefaultPort;
FIdTCPServer.Active := True;


При отправке сообщения на него оно приходит в OnExecute(), как и должно быть, затем я его там ловлю, как и советовал DmSer - примерно так:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
procedure OnExecute(AContext: TIdContext);
var
  Buffer: TIdBytes;
begin
  if AContext.Connection.Socket.InputBuffer.Size > 0 then
    AContext.Connection.Socket.InputBuffer.ExtractToBytes(Buffer);
end;


Затем, специально подключив 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.
procedure OnExecute(AContext: TIdContext);
var
  Buffer: TIdBytes;
begin
  if AContext.Connection.Socket.InputBuffer.Size > 0 then
  begin
    AContext.Connection.Socket.InputBuffer.ExtractToBytes(Buffer);
    begin
      while True do
      begin
        SetLength(Buffer, 0);
        AContext.Connection.Socket.InputBuffer.ExtractToBytes(Buffer);
        if Length(Buffer) = 0 then
          Break;
        ...        
      end;
    end;
  end;
end;


Отрабатывает, но при этом OnExecute() почему-то продолжает постоянно вызываться, хотя входной буфер пуст (разумеется, грузит ЦП и прочее). Само соединение при этом активно и должно таковым оставаться сколь угодно долго. Таким образом, возникает первый вопрос - как правильно реализовать эту простую логику? Длины входного сообщения я не знаю.
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39871211
oklalex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Дополню - OnExecute() всегда начинает вызываться постоянно, пока висит подключение. Хотя бы этого как-то можно избежать?
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39871241
Zelius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
oklalex,

если сервер пассивный, только отвечает, то можно поставить вначале что то типа AContext.Connection.IOHandler.ReadLn и обрабатывать таймаут...
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39871245
Zelius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
oklalex,

или наследовать свой класс потоков, который при создании нового потока будет передавать переменную Loop = False
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
constructor TIdThread.Create(ACreateSuspended: Boolean; ALoop: Boolean; const AName: string);
....
constructor TIdThreadWithTask.Create(ATask: TIdTask; const AName: string);
begin
  inherited Create(True, True, AName);
  FTask := ATask;
end;
.........
procedure TIdThread.Execute;
...............
              if Loop then begin
                while not Stopped do begin
                  try
                    Run;
                  except
                    on E: Exception do begin
                      if not HandleRunException(E) then begin
                        Terminate;
                        raise;
                      end;
                    end;
                  end;
                end;
              end else begin
                try
                  Run;
                except
                  on E: Exception do begin
                    if not HandleRunException(E) then begin
                      Terminate;
                      raise;
                    end;
                  end;
                end;
              end;
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39871255
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
oklalexИ тут есть очень сильная хотелка - как бы так "собрать" это сообщение в первом вызове OnExecute(), зациклив проверку буфера?
Просто встань на место сервера и посмотри на сообщение с его т.зр. Как ему определить, что клиент отстрелялся с данными?

Либо длина в заголовке, либо сигнатура окончания. Можно еще по таймауту ждать, но это ламерство.
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39871260
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Можно весь сеанс обмена с сервером организовать в рамках одного вызова OnExecute.
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39875724
oklalex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Друзья, всем огромное спасибо за внимание и идеи. Прошу прощения, что сразу не ответил. Проблема решилась, перенес на Indy, в который раз убеждаюсь, что это очень продуманная вещь. Вкратце - проблему нашел и тут выше ее уже примерно озвучивали - множество соединений висит в состоянии Time_Wait, обычный TServerSocket это не переваривает, они "висят вечно" и в итоге все останавливается. При большой нагрузке очень быстро. При переносе на Indy сделал ручную проверку, живое ли соединение, и если нет, отключаю. Кстати, у Indy и на этот счет есть штатное решение - SetKeepAliveValues(). Все принимается в одном вызове OnExecute(), спасибо DmSer огромное за то, что навели на правильную идею и привели прототипы необходимых функций.
При желании, можно 100% подобное реализовать и с TServerSocket, но уже не стал заморачиваться и строить велосипеды
...
Рейтинг: 0 / 0
TServerSocket и TService
    #39875726
oklalex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Василий 2oklalexИ тут есть очень сильная хотелка - как бы так "собрать" это сообщение в первом вызове OnExecute(), зациклив проверку буфера?
Просто встань на место сервера и посмотри на сообщение с его т.зр. Как ему определить, что клиент отстрелялся с данными?

Либо длина в заголовке, либо сигнатура окончания. Можно еще по таймауту ждать, но это ламерство.
Согласен полностью, если бы так было сделано - эта тема бы не возникла ) но клиенты многие написаны не мной и так, как Господь на душу положит ( поэтому пришлось подстроить таймауты и работать в условиях тех ограничений, в которые поставлен (
...
Рейтинг: 0 / 0
55 сообщений из 55, показаны все 3 страниц
Форумы / Delphi [игнор отключен] [закрыт для гостей] / TServerSocket и TService
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]