Клиент/сервер Indy TCP с клиентом, действующим в качестве сервера
как инди TIdTCPClient
и TIdTCPServer
используется в следующем сценарии:
Client ---------- initate connection -----------> Server
...
Client <---------------command------------------- Server
Client ----------------response-----------------> Server
...
Client <---------------command------------------- Server
Client ----------------response-----------------> Server
клиент инициирует соединение, но действует как "сервер" (ожидание команд и их выполнение).
на OnExecute
подход TIdTCPServer
не работает хорошо в этом случае (по крайней мере, я не заставляю его работать хорошо). Как я мог это сделать?
Я надеюсь, что вопрос достаточно ясен.
6 ответов
ничто не мешает вам сделать это с компонентом Tidtcpserver Indy.
tidtcpserver только устанавливает соединение. Вам нужно будет реализовать остальное. Таким образом, последовательность фактической отправки и получения может быть такой, какой вы хотите.
поместите этот код в OnExecute событие компонента tidtcpserver:
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's response back to server
IdTCPClient1.Socket.WriteLn(sResponse);
// Show the user the server's final message
ShowMessage(IdTCPClient1.Socket.AllData);
end;
важно отметить, что операторы ReadLn ждут, пока не появятся данные. Это магия, стоящая за всем этим.
Если ваши команды текстового характера, то взгляните на!--0--> компонент, он специально разработан для ситуаций, когда сервер отправляет команды вместо клиента. Сервер может использовать TIdContext.Connection.IOHandler.WriteLn()
или TIdContext.Connection.IOHandler.SendCmd()
отправка команды.
когда клиент подключается к серверу, сервер имеет событие OnConnect с .
свойство это AContext.Connection
, который вы можете хранить вне этого события (скажем, в массиве). Если вы соедините его с IP-адресом или, еще лучше, сгенерированным идентификатором сеанса, а затем ссылаетесь на это соединение по этим критериям, сервер может отправлять adhoc-команды или сообщения клиенту.
надеюсь, что это помогает!
обычно клиент и серверная сторона имеют поток, который читает входящие телеграммы и отправляет ожидающие телеграммы...но такого рода протоколы (отправка/получение, когда и что) зависят от приложения.
очень хорошей отправной точкой, как клиентская сторона может быть реализована с помощью потока, прослушивания сообщений с сервера, является клиентский компонент Indy Telnet (TIdTelnet в папке протоколов).
клиент Indy telnet подключается к серверу telnet и использует только одна розетка написать и чтение данных. Чтение происходит в потоке прослушивателя.
этот дизайн можно легко адаптировать для создания распределенного программного обеспечения обмена сообщениями, такого как чат так далее., а также показывает, насколько легко протокол может быть отделен от сетевого уровня с помощью блокирующих сокетов.
с Indy это невозможно по дизайну:
Indy поддерживает только инициированную клиентом связь, что означает, что сервер может отправлять ответ только на запросы клиента.
Самый простой способ (но не самый умный), чтобы получить то, что вы хотите использовать пулл-процесс. Управляемые таймером клиенты спрашивают сервер, есть ли новая команда. Конечно, это вызовет много трафика-накладные расходы и в зависимости от вашего pull-intervall есть задержка.
В качестве альтернативы вы могли бы используйте другую библиотеку, такую как ICS (http://www.overbyte.be/eng/products/ics.html)