简体   繁体   中英

Send and receive simultaneously with TIdTCPServer

It is always advised to perform all the sending / receiving tasks in OnExecute event handler of TIdTCPServer , but I do not understand following:

How to wait for a specific sequence on input and at the same time send some data to the same client? I need not a command-response sequence, but I need to:

  • send live data constantly
  • while receiving edited data back
  • and receiving commands and provide responses for them.

For example, if we are waiting for 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;

It is important that when sending unsolicited data and response data using the same connection, don't overlap the outgoing messages, or else you will corrupt your protocol. It is best to have only 1 thread do all of the sending so that one message gets sent in full before another message is sent. Just make sure you design your protocol to allow unsolicited data to be sent after the client sends a command and before it receives a response. Each message should describe what kind of message it is, in such a way that the client can detect a response and match it to an earlier command, while handling unsolicited data as-is.

There is a few different ways you can handle the sending:

  • use separate threads for reading and sending. For instance, have the OnExecute thread handle all of the reading, and use another worker thread to handle all of the sending. If OnExecute receives an inbound command that needs to send a response, pass the response data to the sending thread (in a thread-safe manner) so it can send the response when safe to do so in between unsolicited messages.

  • have the OnExecute thread handle both reading and sending. Continuously send outgoing unsolicited data as needed, and periodically check for inbound data using the IOHandler.InputBufferIsEmpty() and IOHandler.CheckForSourceOnData() methods to detect when an inbound message needs to be read.

  • otherwise, like Jerry Dodge suggested in comments, just use separate connections, one for command-response data, and one for unsolicited data.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM