Подтвердить что ты не робот

Клиент/сервер Indy TCP с клиентом, действующим в качестве сервера

Как можно использовать Indy TIdTCPClient и TIdTCPServer в следующем сценарии:

Client  ---------- initate connection -----------> Server
...
Client  <---------------command------------------- Server
Client  ----------------response-----------------> Server
...
Client  <---------------command------------------- Server
Client  ----------------response-----------------> Server

Клиент инициирует подключение, но действует как "сервер" (ожидание команд и их выполнение).

Подход OnExecute TIdTCPServer не работает в этом случае (по крайней мере, я не получаю его, чтобы он работал хорошо). Как я могу это сделать?

Надеюсь, этот вопрос достаточно ясен.

4b9b3361

Ответ 1

Нет ничего, что помешало бы вам сделать это с помощью компонента Indy TIdTCPServer.

TIdTCPServer только устанавливает соединение. Вам нужно будет реализовать все остальное. Таким образом, последовательность фактической отправки и получения может быть любой, что вы хотите.

Поместите этот код в свой компонент TIdTCPServer. Событие OnExecute:

var
  sName: String;
begin
  // Send command to client immediately after connection
  AContext.Connection.Socket.WriteLn('What is your name?');
  // Receive response from client
  sName := AContext.Connection.Socket.ReadLn;
  // Send a response to the client
  AContext.Connection.Socket.WriteLn('Hello, ' + sName + '.');
  AContext.Connection.Socket.WriteLn('Would you like to play a game?');
  // We're done with our session
  AContext.Connection.Disconnect;
end;

Здесь вы можете настроить TIdTCPServer просто:

IdTCPServer1.Bindings.Clear;
IdTCPServer1.Bindings.Add.SetBinding('127.0.0.1', 8080);
IdTCPServer1.Active := True;

Это говорит серверу прослушивать только адрес петли, на порту 8080. Это предотвращает подключение к нему любого, кроме вашего компьютера.

Затем для подключения вашего клиента вы можете перейти в командную строку Windows и ввести следующее:

telnet 127.0.0.1 8080

Здесь вывод:

Как вас зовут?

Марк

Привет, Маркус.

Хотели бы вы сыграть в игру?

Соединение с хостом потеряно.

У вас нет telnet? Здесь, как установить клиент telnet на Vista и 7.

Или с помощью клиента TIdTCP вы можете сделать это:

var
  sPrompt: String;
  sResponse: String;
begin
  // Set port to connect to
  IdTCPClient1.Port := 8080;
  // Set host to connect to
  IdTCPClient1.Host := '127.0.0.1';
  // Now actually connect
  IdTCPClient1.Connect;
  // Read the prompt text from the server
  sPrompt := IdTCPClient1.Socket.ReadLn;
  // Show it to the user and ask the user to respond
  sResponse := InputBox('Prompt', sPrompt, '');
  // Send user response back to server
  IdTCPClient1.Socket.WriteLn(sResponse);
  // Show the user the server final message
  ShowMessage(IdTCPClient1.Socket.AllData);
end;

Важно отметить, что инструкции ReadLn ожидают, пока не появятся данные. Это волшебство за всем этим.

Ответ 2

Если ваши команды носят текстовый характер, посмотрите на компонент TIdCmdTCPClient, он специально разработан для ситуаций, когда сервер отправляет команды вместо клиента. Для отправки команд сервер может использовать TIdContext.Connection.IOHandler.WriteLn() или TIdContext.Connection.IOHandler.SendCmd().

Ответ 3

Когда клиент подключается к серверу, сервер имеет событие OnConnect с параметром AContext: TIdContext.

Свойство это AContext.Connection, которое вы можете хранить вне этого события (скажем, в массиве). Если вы соедините его с IP или еще лучше сгенерированным идентификатором сеанса, а затем ссылайтесь на это соединение по этим критериям, вы можете затем отправить сервер клиентам команды adhoc или сообщения.

Надеюсь, это поможет!

Ответ 4

обычно клиент и сторона сервера имеют поток, который считывает входящие телеграммы и отправляет ожидающие телеграммы... но такие протоколы (send/receive, when и what) зависят от приложения.

Ответ 5

Очень хорошей отправной точкой, как клиентская сторона может быть реализована с использованием потока, прислушиваясь к сообщениям с сервера, является клиентский компонент Indy Telnet (TIdTelnet в папке "Протоколы" ).

Клиент telnet Indy подключается к серверу telnet и использует только один сокет для записи и чтения данных. Чтение происходит в потоке слушателя.

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

Ответ 6

С Indy это невозможно по дизайну:
Indy поддерживает только инициированную клиентом связь, что означает, что сервер может отправлять ответ только на запросы клиента.
Самый простой способ (но не самый умный) получить то, что вы хотите, это использовать pull-process. Контролируемые таймером, клиенты спрашивают сервер, есть ли новая команда. Конечно, это вызовет много трафика, и в зависимости от вашего прерывания между задержкой есть задержка.
В качестве альтернативы вы можете использовать другую библиотеку, такую ​​как ICS (http://www.overbyte.be/eng/products/ics.html)