Изпращайте и получавайте едновременно с TIdTCPServer

Винаги се препоръчва да изпълнявате всички задачи за изпращане/получаване в OnExecute манипулатор на събития на TIdTCPServer, но не разбирам следното:

Как да изчакате конкретна последователност при въвеждане и в същото време да изпратите някои данни на същия клиент? Нямам нужда от последователност команда-отговор, но трябва да:

  • изпращайте постоянно данни на живо
  • докато получават обратно редактирани данни
  • и получаване на команди и предоставяне на отговори за тях.

Например, ако чакаме CR-LF:

procedure TSocketServer._serverExecute(AContext: TIdContext);
var
  msg: string;
begin
  msg := AContext.Connection.IOHandler.ReadLn();
  //Here we are only if CRLF was detected.
  //How to send while we are waiting?
  _log(msg);
end;

person Paul    schedule 12.04.2019    source източник
comment
Отворете множество връзки. Това изисква множество TCP компоненти.   -  person Jerry Dodge    schedule 12.04.2019
comment
Като се замисля, можете да се разминете само с 1 TCP сървър, тъй като той приема връзки от множество клиенти. Но от страна на клиента ще ви трябват две и някакъв начин да кажете на сървъра кое кое е.   -  person Jerry Dodge    schedule 12.04.2019
comment
Задайте свойството за изчакване на IOHander, така че функцията ReadLn да продължи след известно време, дори ако не са прочетени байтове.   -  person nolaspeaker    schedule 12.04.2019
comment
Като алтернатива, преди да се обадите на IOHandler.ReadLn(), извикайте IOHandler.CheckForDataOnSource() с изчакване и проверете с IOHandler.InputBufferIsEmpty()   -  person Remy Lebeau    schedule 12.04.2019
comment
@JerryDodge Но от страна на клиента ще ви трябват два и някакъв начин да кажете на сървъра кой кой е - можете да накарате сървъра да слуша на 2 различни порта. Тогава клиентът може да отвори връзки към двата порта, ако е необходимо.   -  person Remy Lebeau    schedule 12.04.2019
comment
@Remy Наистина има много начини, аз предлагах една идея. Но аз го гледах от гледна точка на защитната стена - колкото по-малко портове за отваряне, толкова по-лесно.   -  person Jerry Dodge    schedule 12.04.2019


Отговори (1)


Важно е, когато изпращате непоискани данни и данни за отговор, използвайки една и съща връзка, да не припокривате изходящите съобщения, в противен случай ще повредите протокола си. Най-добре е само 1 нишка да извършва цялото изпращане, така че едно съобщение да бъде изпратено изцяло, преди да бъде изпратено друго. Просто се уверете, че проектирате своя протокол, за да позволите изпращането на нежелани данни, след като клиентът изпрати команда и преди да получи отговор. Всяко съобщение трябва да описва какъв вид съобщение е по такъв начин, че клиентът да може да открие отговор и да го съпостави с по-ранна команда, като същевременно обработва непоисканите данни такива, каквито са.

Има няколко различни начина, по които можете да се справите с изпращането:

  • използвайте отделни теми за четене и изпращане. Например, накарайте нишката OnExecute да обработва цялото четене и използвайте друга работна нишка, за да обработва цялото изпращане. Ако OnExecute получи входяща команда, която трябва да изпрати отговор, прехвърлете данните за отговор към изпращащата нишка (по безопасен за нишката начин), така че да може да изпрати отговора, когато е безопасно да го направи между непоискани съобщения.

  • нишката OnExecute да обработва както четенето, така и изпращането. Непрекъснато изпращайте изходящи непоискани данни според нуждите и периодично проверявайте за входящи данни, като използвате методите IOHandler.InputBufferIsEmpty() и IOHandler.CheckForSourceOnData(), за да откриете кога входящо съобщение трябва да бъде прочетено.

  • в противен случай, както Джери Додж предложи в коментарите, просто използвайте отделни връзки, една за данни команда-отговор и една за непоискани данни.

person Remy Lebeau    schedule 12.04.2019