powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / TServerSocket и TService
25 сообщений из 55, страница 2 из 3
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
25 сообщений из 55, страница 2 из 3
Форумы / Delphi [игнор отключен] [закрыт для гостей] / TServerSocket и TService
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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