Я использую 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*>
чтобы сохранить все соединения, который работает нормально.
Вот пример того, как отправить сообщение от 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();
}
Вы сказали
…Это означает, что клиенты не будут знать, когда открывать соединение. Я думаю, я ищу какое-то событие, которое ждет сообщения от сервера.
В ответе выше есть очень хорошие варианты, если вы хотите остаться с одним TCP-соединением, оставить его открытым и отслеживать сообщения.
Другой вариант, который был упомянут в комментарии, состоял в том, чтобы (также) установить соединение UDP. На каждом из ваших «клиентов» создайте iDUDPServer, который прослушивает определенный порт (это будет порт, отличный от вашего TCP-соединения). На вашем «Сервере» создайте TIdUDPClient. Обратите внимание на разницу в терминологии: вы установите UDPServer на то, что вы называете своим TCP-клиентом, и наоборот..
Отправьте UDP-сообщение своим «Клиентам» с сервера, используя это. Вы поймаете сообщение в событии (Client’s) IdUDPServer OnUDPRead.
Если все ваши клиенты находятся в одном сегменте сети, вы можете использовать широковещательную рассылку UDP для отправки одного сообщения всем прослушивающим клиентам. Если нет, отправляйте сообщения каждому из ваших клиентов, используя их IP-адрес.
Одной из ваших проблем было отсутствие примеров C ++. Извините, я не могу помочь с кодом C ++. Вот псевдокод / процедура, вам придется управлять синтаксисом языка:
На вашем «Клиенте»,
создайте TIdUDPServer (поместите его в форму, он должен быть доступен для прослушивания).
Установите DefaultPort на порт прослушивания (установите другие параметры, если хотите)
На вашем «Сервере»
создать TIdUPDClient.
отправьте ваше сообщение на определенный IP-адрес:
a: Установите IdUDPClient.Host (цель)
b: установить IdUDPClient.Port (цель)
c: IdUDPClient.Send (msg)
ИЛИ, вы можете вещать всем в своем сегменте сети с:
a: IdUDPClient.Broadcast (msg, TargetPort)
«Msg» будет представлено на ваших клиентах в событии IdUDPServerUDPRead в качестве параметра AData.
Эта опция может быть немного более сложной, поскольку задействованы два пути сообщения, но она не требует, чтобы клиенты открывали TCP-соединения с вашим сервером, и не требует настройки цикла мониторинга для входящих сообщений. Фактически, это может использоваться, чтобы объявить местоположение вашего сервера, если клиенты не знали, должны были соединиться. Эта связь UDP к тому же к вашему существующему соединению TCP, поэтому эти соединения остаются без изменений.