Создание Многопоточного Сервера TCP/IP

Я хочу создать сервер TCP/IP, который будет использоваться до 100 параллельных клиентов, но все еще не уверенный, как начать.

по крайней мере, мне нужен сервер к этому:

  1. Слушание клиента и хранилища все их на массиве или списке.
  2. для каждого клиента это должно получить и отправить данные на основе, он - клиентское состояние.
  3. Сервер должен обновить клиентский список, когда кто-то соединяется или разъединяется.
  4. Предпочтите работать сервисом с GUI для управления им.

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

10
задан paxos1977 18 February 2010 в 17:36
поделиться

7 ответов

Поле .RecordCount из памяти с VB6/ADO давным-давно не возвращает значимые данные, пока не будет выполнен переход к концу набора записей.

rs.MoveLast
rs.MoveFirst
Debug.Print rs.RecordCount

Однако при этом необходимо убедиться в наличии соответствующего типа курсора (т.е. не только для пересылки).

Единственное другое решение, которое я могу придумать, это сделать отдельный SELECT COUNT (*) FROM my

-121--3320619-

удалить глобальный оператор

>>> x
0
>>> def f1():
    x = 1
    print(x)
    def f2():
        print(x)
    f2()
    print(x)


>>> f1()
1
1
1

, если требуется изменить переменную x из f1 , то в каждой функции необходимо использовать глобальный оператор.

-121--4716274-

Необходимо использовать многопоточный сервер TidTCPServer . Вам не нужно управлять потоками. Все прозрачно, поэтому в пути, в котором вы пишете приложение для одного клиента, в (почти) том же пути вы будете писать его для многих. См. событие OnConnect . Существует параметр TidContext , внутри которого имеется список TThreadList. Это событие можно использовать для «регистрации »/добавления клиентов в пользовательский массив/список и OnDisconnect для удаления клиентов.

Событие OnExecute инициируется при получении сервером сообщения. Используйте его параметры для чтения отправляемого сообщения.

Также необходимо другое приложение, которое будет вашим клиентом, с помощью TidTCPClient . В этом приложении будет задан адрес сервера (см. свойство Host), а также порт, который должен совпадать с адресом сервера. Необходимо вызвать Connect (когда сервер запущен) и отправить последовательности с использованием метода SendCmd . (См. также IOHandler.WriteLn , если вы хотите)

Есть и другие вещи, но я думаю, что этого достаточно, чтобы начать. Также вы можете разместить на форумах Embarcadero в форуме .Delphi.Winsock, где участники команды Indy плавают. Или, возможно, вы можете спросить прямо в .Delphi.Non-Technical и ребята там будут направлять вас.

Другой подход - DataSnap , который является более объектно-ориентированным слоем над Indy (не путать с DBX), который дает ваш JSON, REST и другие вкусности. См. небольшой обзор здесь .

8
ответ дан 3 December 2019 в 21:21
поделиться

Другой вариант библиотеки Delphi - synapse , который обеспечивает простую структуру, которую можно легко расширить. В добавленных файлах доступна демонстрация IOCPPool , которая может оказаться полезной.

Synapse - это скорее структура классов, чем библиотека компонентов. Существует яркое и активное сообщество пользователей, готовое поддержать любые вызовы. Я без проблем использую эту библиотеку в Delphi 2010 (хотя использую последнюю разрабатываемую версию от SVN).

Поскольку они не являются компонентами, очень легко использовать классы в простых консольных приложениях или службах Windows.

3
ответ дан 3 December 2019 в 21:21
поделиться

Indy - ваш лучший выбор: 1000 клиентов - это не так уж и много: я разработал сервер, который должен был обслуживать 4-5 тысяч клиентов, и он работает как прелесть.

  1. Прослушивание клиента и сохранение их всех в массиве или списке. + 3. Сервер должен обновлять список клиентов, когда кто-то подключается или отключается.

-> Что касается списка клиентов, вы можете в цикле перебрать член TThreadList TidTCPServer (версия 9.0), в котором хранятся все «живые» потоки, каждый поток «эквивалентен» клиентскому соединению, хотя потоки могут пережить клиентское соединение, но вы можете исправить это, установив соответствующее значение тайм-аута соединения. Если вы хотите, вы также можете поддерживать свой собственный список клиентов (например, наследовать от TList или создать Generics.Collection): вы должны добавить информацию о клиенте после события onConnect (класс tidPeerThread предоставляет всю информацию о клиенте: IP ...)

Затем вы должны периодически просматривать этот список и проверять наличие активных соединений (например, команду ping) и уничтожать / удалять всех зомби.

[indy documentation] Обработчик событий для попыток подключения однорангового потока.

свойство OnConnect: TIdServerThreadEvent;

Описание

OnConnect - это обработчик событий для TIdServerThreadEvents. OnConnect возникает, когда TIdPeerThread пытается подключиться к TIdTCPServer.

OnConnect получает AThread в качестве параметра, представляющего поток TIdPeerThread, запрашивающий соединение.

Назначьте OnConnect процедуру обработчика событий TIdServerThreadEvent. [/ indy documentation]

  1. для каждого клиента он должен получать и отправлять данные в зависимости от его статуса: -> проверьте исходный код демо-версии клиента чата и сервера для получения подробного примера.

  2. Предпочитайте работать как сервис с графическим интерфейсом для управления им: вы можете разработать приложение-сервис, которое будет регистрировать всю свою активность в базе данных, и второе приложение, которое будет обращаться к этой базе данных и показывать всю доступную статистику (количество клиентов ... ).

, а вот ссылки на Indy 9.0 (источники и документация): http: //www.indyproject.org / downloads / Indy_9_00_14_src.zip http://www.indyproject.org/downloads/Indy-9-0-Help-WinHelp.zip

И вот книга Indy, хотя я не думаю, что вы бы он понадобится после прочтения документации: Подробное описание Indy: http://www.atozed.com/Indy/Book/index.EN.aspx

Найдите здесь хорошее руководство: http://www.devarticles.com/c/a/Delphi-Kylix/Creating-Chat-Application-with-Borland-DelphiIndy-The-Client/

Удачи

2
ответ дан 3 December 2019 в 21:21
поделиться

100 сокетов - не так много. Вы можете использовать что-то вроде epoll (), но для этого случая я бы просто установил один FD_SET со всеми сокетами, select () для всего набора, затем проверил бы каждый и обработал их в последовательность. Если бы мне пришлось сделать что-то, что потенциально могло бы занять много времени, я бы использовал пул потоков для обработчиков сообщений.

1
ответ дан 3 December 2019 в 21:21
поделиться

Некоторые отличные наборы компонентов, которые полезны для ситуаций, подобных вашей (и многих других): kbmMW и RemObjects . Есть и другие хорошие наборы, я думаю, вы можете выполнить поиск в архиве или задать вопрос в группе новостей Embarcaderos Delphi Thirdpartytools. Вы можете искать здесь архивы: http://codenewsfast.com/

0
ответ дан 3 December 2019 в 21:21
поделиться

Я недавно столкнулся с этой проблемой. Вот ссылка на пример C ++ с использованием EPOLL для управления сотнями многоадресных сокетов. Вашим будет TCP / IP, но на самом деле это простое изменение.

Какой бы метод вы ни выбрали, для более чем 100 одновременных сокетов / клиентов вы захотите использовать модель потоков, основанную на опросе, выборе или предпочтительном epoll, если ваша платформа поддерживает это.

http://anthonyvirtuoso.com/public/dokuwiki/doku.php/projects:multiplexreceiverepoll

@jfawcett - выбор более чем ~ 50 FD приводит к довольно значительной загрузке ЦП в зависимости от того, как часто вы фактически выполняете Выбрать. В моем комментарии выше этот образец класса изначально использовал select, но, увидев стоимость ЦП (valgrind w / callgrind), я переключился на epoll. Но, безусловно, select - допустимый вариант.

0
ответ дан 3 December 2019 в 21:21
поделиться

На платформе Windows вам, вероятно, лучше избегать select для большого числа одновременных соединений (100 соединений не является большим числом соединений). Однако avirtuos прав в том, что вы хотите избежать любых моделей "поток на соединение". Наиболее эффективным подходом в Windows является использование перекрывающихся портов ввода-вывода и портов завершения ввода-вывода. Это позволяет управлять 10 тысячами соединений с помощью небольшого количества потоков (2 или 3, возможно).

У меня нет опыта работы в Delphi, поэтому я понятия не имею, насколько легко взаимодействовать с кодом C++, НО у меня есть бесплатный серверный фреймворк C++ I/O Completion Port (доступен с здесь), который, по крайней мере, покажет вам, как работает стандартный Win32 I/O Completion Port API. Это может быть полезно для вас, и вы, возможно, сможете сделать что-то подобное в Delphi.

3
ответ дан 3 December 2019 в 21:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: