idTCPServer отправляет сообщение в idTCPClient без активности клиента

Я использую Embarcadero C ++ Builder и знаю, как открыть соединение и ждать ответа со стороны сервера (клиент может открыть соединение, отправить сообщение и прочитать сообщение, которое было отправлено с сервера, до закрытия соединения).

Сторона клиента:

IdTCPClient1->Connect();
IdTCPClient1->Socket->WriteLn("message from client");
ShowMessage(IdTCPClient1->Socket->ReadLn());
IdTCPClient1->Disconnect();

Сторона сервера:

ShowMessage(AContext->Connection->Socket->ReadLn());
AContext->Connection->Socket->WriteLn("Message from server");
AContext->Connection->Disconnect();

Теперь обмен сообщениями возможен, если клиент открывает соединение на стороне клиента, но мне нужен сервер, чтобы отправить сообщение всем пользователям, а это значит, что клиенты не будут знать, когда открывать соединение. Я думаю, я ищу какое-то событие, которое ждет сообщения от сервера. Все примеры, которые я нашел, находятся на Delphi, а не на C ++. Кроме того, когда каждый клиент подключается в первый раз, я сделал vector<TIdContext*> чтобы сохранить все соединения, который работает нормально.

0

Решение

Вот пример того, как отправить сообщение от TIdTCPServer всем подключенным клиентам:

TIdContext *MyContext;
TList *ClientsList = IdTCPServer1->Contexts->LockList();
try {
for (int i = 0; i < ClientsList->Count; i++) {
MyContext = (TIdContext*) ClientsList->Items[i];
MyContext->Connection->IOHandler->WriteLn("Message for all the clients");
}
__finally {
IdTCPServer1->Contexts->UnlockList();
}
0

Другие решения

Вы сказали

…Это означает, что клиенты не будут знать, когда открывать соединение. Я думаю, я ищу какое-то событие, которое ждет сообщения от сервера.

В ответе выше есть очень хорошие варианты, если вы хотите остаться с одним TCP-соединением, оставить его открытым и отслеживать сообщения.

Другой вариант, который был упомянут в комментарии, состоял в том, чтобы (также) установить соединение UDP. На каждом из ваших «клиентов» создайте iDUDPServer, который прослушивает определенный порт (это будет порт, отличный от вашего TCP-соединения). На вашем «Сервере» создайте TIdUDPClient. Обратите внимание на разницу в терминологии: вы установите UDPServer на то, что вы называете своим TCP-клиентом, и наоборот..

Отправьте UDP-сообщение своим «Клиентам» с сервера, используя это. Вы поймаете сообщение в событии (Client’s) IdUDPServer OnUDPRead.

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

Одной из ваших проблем было отсутствие примеров C ++. Извините, я не могу помочь с кодом C ++. Вот псевдокод / ​​процедура, вам придется управлять синтаксисом языка:

На вашем «Клиенте»,

  1. создайте TIdUDPServer (поместите его в форму, он должен быть доступен для прослушивания).

  2. Установите DefaultPort на порт прослушивания (установите другие параметры, если хотите)

  3. Назначьте код события для IdUDPServerUDPRead (AThread: TIdUDPListenerThread;
    AData: TArray; ABinding: TIdSocketHandle). Входящие данные находятся в AData. Вы можете подтвердить IP-адрес источника, посмотрев на ABinding.PeerIP, если вам это нужно.

На вашем «Сервере»

  1. создать TIdUPDClient.

  2. отправьте ваше сообщение на определенный IP-адрес:

    a: Установите IdUDPClient.Host (цель)

    b: установить IdUDPClient.Port (цель)

    c: IdUDPClient.Send (msg)

    ИЛИ, вы можете вещать всем в своем сегменте сети с:

    a: IdUDPClient.Broadcast (msg, TargetPort)

  3. «Msg» будет представлено на ваших клиентах в событии IdUDPServerUDPRead в качестве параметра AData.

Эта опция может быть немного более сложной, поскольку задействованы два пути сообщения, но она не требует, чтобы клиенты открывали TCP-соединения с вашим сервером, и не требует настройки цикла мониторинга для входящих сообщений. Фактически, это может использоваться, чтобы объявить местоположение вашего сервера, если клиенты не знали, должны были соединиться. Эта связь UDP к тому же к вашему существующему соединению TCP, поэтому эти соединения остаются без изменений.

0

По вопросам рекламы [email protected]