Indy 9
|
TIdTCPConnection = class(TIdComponent)
TIdTCPConnection publishes properties that allow configuration of the transport mechanism for the connection including ReadTimeout, RecvBufferSize, and SendBufferSize, ASCIIFilter, Intercept, IOHandler, and ASCIIFilter.
TIdTCPConnection also exposes event handlers that provide notifications of actions performed on the connection including OnDisconnected, OnWorkBegin, OnWork, and OnWorkEnd.
TIdTCPConnection is the ancestor class for TIdTCPClient and TIdTCPServer.
property ASCIIFilter: boolean;
ASCIIFilter is used to insure that character data in the Indy buffer will contain values that can be represented using the US-ASCII character set (Decimal 0 through Decimal 127).
ASCIIFilter is used in ReadFromStack.
property ClosedGracefully: Boolean;
CloseGracefully is updated in ReadFromStack when a the socket handle for the connection is ready for read operations.
property Greeting: TIdRFCReply;
Greeting is initialized in the Create constructor, and freed in Destroy. Greeting is normally updated by descendant classes, like TIdNNTP, TIdFTP, etc., that provide a welcome message during their overridden connect method.
property InputBuffer: TIdManagedBuffer;
Values in InputBuffer are affected by methods that extract data in various formats like CurrentReadBuffer, ReadStream, ReadLn, and ReadStrings. Most applications will use the methods that extract ordinal data types like ReadCardinal, ReadChar, ReadInteger, ReadSmallInt, and ReadString.
Note: InputBuffer is not the same as the internal buffer used for receive operations from the TCP/IP protocol stack, as indicated in RecvBufferSize.
property Intercept: TIdConnectionIntercept;
The Intercept must be Enabled to allow Intercept actions to be performed.
property IOHandler: TIdIOHandler;
IOHandler is used in methods that perform low-level read or write operations like ReadFromStack and WriteBuffer. IOHandler is also used in methods that access the connection status like CheckForDisconnect, Connected, DisconnectSocket, and Disconnect.
When accessing IOHandler in application code, always cast the IOHandler to the correct descendant class. This is needed to access any methods or properties in the descendant that cannot be represented in the ancestor class at runtime.
property LastCmdResult: TIdRFCReply;
property MaxLineAction: TIdMaxLineAction;
property MaxLineLength: Integer;
MaxLineLength is used in ReadLn and InputLn when the maximum line length argument to the method is -1 indicating that the property value should be used.
property OnDisconnected: TNotifyEvent;
An application must assign a procedure to OnDisconnected to allow a response to the event notification.
property OnWork;
AWorkMode indicates the operation performed and the notification sent to OnWork. AWorkMode can be contain one of the following values:
AWorkCount indicates the number of bytes affected by the operation sent to OnWork.
The event TWorkEvent is implemented in IdComponent.pas.
TIdTCPConnection publishes the OnWork event. OnWork is not published in the ancestor class TIdComponent.
property OnWorkBegin;
AWorkMode indicates the operation performed and the notification sent to OnWorkBegin. AWorkMode can contain one of the following values:
AWorkCountMax indicates the maximum number of bytes expected for the operation sent to OnWorkBegin, or 0 when the number of bytes not known.
The event TWorkEvent is implemented in IdComponent.pas.
TIdTCPConnection publishes the OnWorkBegin event. OnWork is not published in the ancestor class TIdComponent.
property OnWorkEnd;
AWorkMode indicates the operation performed and the notification sent to OnWork. AWorkMode can contain one of the following values:
AWorkCount contains the number of bytes affected by the operation.
TIdTCPConnection publishes the OnWorkEnd event. OnWorkEnd is not published in the ancestor class TIdComponent.
property ReadLnSplit: Boolean;
property ReadLnTimedOut: Boolean;
ReadLnTimedOut is updated in the ReadLn method, and is set to True when the return value for ReadFromStack is 0.
property ReadTimeout: Integer;
ReadTimeout is used in ReadFromStack.
property RecvBufferSize: Integer;
The default value for RecvBufferSize is 8192 bytes, and is asssigned in Create.
property SendBufferSize: Integer;
SendBufferSize is used in WriteStream to determine if the number of "chunks" needed to Write the TStream contents. When the stream is larger that SendBufferSize, multiple "chunks" will be used.
property Socket: TIdIOHandlerSocket;
AConnection.Socket.Binding.IP := sIPAddress; AConnection.Socket.Binding.Port := iPort; sPeer := AConnection.Socket.Binding.PeerIP; iPeer := AConnection.Socket.Binding.PeerPort; TIdIOHandlerSocket(AConnection.IOHandler).Binding.IP := sIPAddress; TIdIOHandlerSocket(AConnection.IOHandler).Binding.Port := iPort; sPeer := TIdIOHandlerSocket(AConnection.IOHandler).Binding.PeerIP; iPeer := TIdIOHandlerSocket(AConnection.IOHandler).Binding.PeerPort;
Socket will contain the value Nil when the assigned IOHandler is not a TIdIOHandlerSocket class instance.
function AllData: string; virtual;
Note: Do not use AllData unless the protocol you are using works in this manner. Protocols which support AllData include Finger, Quote of the Day, and WhoIs.
procedure CancelWriteBuffer;
procedure Capture(ADest: TStream; const ADelim: string = '.'; const AIsRFCMessage: Boolean = True); overload; procedure Capture(ADest: TStream; out VLineCount: Integer; const ADelim: string = '.'; const AIsRFCMessage: Boolean = True); overload; procedure Capture(ADest: TStrings; const ADelim: string = '.'; const AIsRFCMessage: Boolean = True); overload; procedure Capture(ADest: TStrings; out VLineCount: Integer; const ADelim: string = '.'; const AIsRFCMessage: Boolean = True); overload;
ADelim is the delimiter used to determine if all data has been read from the connection. ADelim will appear in a line with no other data when all data has been captured. The default delimiter is '.', as used in most RFC-compliant protocols.
AIsRFCMessage indicates that Capture is reading an RFC 822 message where a line may start with the characters '..'. Capture will convert this character sequence to a single '.' character. A single '.' character in a line indicates the end of the RFC 822 message.
Capture triggers the OnWorkBegin event handler with wmRead mode before reading data from the connection. Capture calls ReadLn to retrieve data from the connection until the delimiter specified in ADelim is received. Each line is written to the ADest object reference upon receipt. Capture triggers the OnWorkEnd event handler with wmRead mode when all data has been captured from the connection.
procedure Capture(ADest: TStream; const ADelim: string = '.'; const AIsRFCMessage: Boolean = True); overload; procedure Capture(ADest: TStream; out VLineCount: Integer; const ADelim: string = '.'; const AIsRFCMessage: Boolean = True); overload; procedure Capture(ADest: TStrings; const ADelim: string = '.'; const AIsRFCMessage: Boolean = True); overload; procedure Capture(ADest: TStrings; out VLineCount: Integer; const ADelim: string = '.'; const AIsRFCMessage: Boolean = True); overload;
ADelim is the delimiter used to determine if all data has been read from the connection. ADelim will appear in a line with no other data when all data has been captured. The default delimiter is '.', as used in most RFC-compliant protocols.
AIsRFCMessage indicates that Capture is reading an RFC 822 message where a line may start with the characters '..'. Capture will convert this character sequence to a single '.' character. A single '.' character in a line indicates the end of the RFC 822 message.
Capture triggers the OnWorkBegin event handler with wmRead mode before reading data from the connection. Capture calls ReadLn to retrieve data from the connection until the delimiter specified in ADelim is received. Each line is written to the ADest object reference upon receipt. Capture triggers the OnWorkEnd event handler with wmRead mode when all data has been captured from the connection.
procedure Capture(ADest: TStream; const ADelim: string = '.'; const AIsRFCMessage: Boolean = True); overload; procedure Capture(ADest: TStream; out VLineCount: Integer; const ADelim: string = '.'; const AIsRFCMessage: Boolean = True); overload; procedure Capture(ADest: TStrings; const ADelim: string = '.'; const AIsRFCMessage: Boolean = True); overload; procedure Capture(ADest: TStrings; out VLineCount: Integer; const ADelim: string = '.'; const AIsRFCMessage: Boolean = True); overload;
ADelim is the delimiter used to determine if all data has been read from the connection. ADelim will appear in a line with no other data when all data has been captured. The default delimiter is '.', as used in most RFC-compliant protocols.
AIsRFCMessage indicates that Capture is reading an RFC 822 message where a line may start with the characters '..'. Capture will convert this character sequence to a single '.' character. A single '.' character in a line indicates the end of the RFC 822 message.
Capture triggers the OnWorkBegin event handler with wmRead mode before reading data from the connection. Capture calls ReadLn to retrieve data from the connection until the delimiter specified in ADelim is received. Each line is written to the ADest object reference upon receipt. Capture triggers the OnWorkEnd event handler with wmRead mode when all data has been captured from the connection.
procedure Capture(ADest: TStream; const ADelim: string = '.'; const AIsRFCMessage: Boolean = True); overload; procedure Capture(ADest: TStream; out VLineCount: Integer; const ADelim: string = '.'; const AIsRFCMessage: Boolean = True); overload; procedure Capture(ADest: TStrings; const ADelim: string = '.'; const AIsRFCMessage: Boolean = True); overload; procedure Capture(ADest: TStrings; out VLineCount: Integer; const ADelim: string = '.'; const AIsRFCMessage: Boolean = True); overload;
ADelim is the delimiter used to determine if all data has been read from the connection. ADelim will appear in a line with no other data when all data has been captured. The default delimiter is '.', as used in most RFC-compliant protocols.
AIsRFCMessage indicates that Capture is reading an RFC 822 message where a line may start with the characters '..'. Capture will convert this character sequence to a single '.' character. A single '.' character in a line indicates the end of the RFC 822 message.
Capture triggers the OnWorkBegin event handler with wmRead mode before reading data from the connection. Capture calls ReadLn to retrieve data from the connection until the delimiter specified in ADelim is received. Each line is written to the ADest object reference upon receipt. Capture triggers the OnWorkEnd event handler with wmRead mode when all data has been captured from the connection.
procedure CheckForDisconnect(const ARaiseExceptionIfDisconnected: boolean = true; const AIgnoreBuffer: boolean = false); virtual;
When the connection has been ClosedGracefully, and the IOHandlerSocket.Binding has an allocated socket handle, then DisconnectSocket is called to force the socket handle to be deallocated.
Under some conditions, CheckForDisconnect can raise an EIdConnClosedGracefully exception. The exception can occur when the Indy Read buffer is empty or should be ignored (as indicated in AIgnoreBuffer), and ARaiseExceptionIfDisconnected indicates that the exception is desired.
For a Server connection, this indicates that the client has disconnected the socket connection normally. The Exception is used to notify Server handling code. The exception is normal and will only happen from within the IDE, not while your program is running as an EXE. If you do not want to see this, add the EIdConnClosedGracefully exception or EIdSilentException to the IDE options as exceptions not to break on. From the IDE, press F9 and Indy will catch and handle the exception.
For a Client connection, this indicates that the server has disconnected the socket connection normally, but the client has attempted to read or write using the closed connection. You should trap this error using a try..except block.
Please see the FAQ at http://www.nevrona.com/Indy/FAQ.html for additional information.
procedure CheckForGracefulDisconnect(const ARaiseExceptionIfDisconnected: Boolean = True); virtual;
ReadFromStack updates the ClosedGracefully property and performs exception handling as specified in ARaiseExceptionIfDisconnected.
function CheckResponse(const AResponse: SmallInt; const AAllowedResponses: array of SmallInt): SmallInt; virtual;
procedure ClearWriteBuffer;
procedure CloseWriteBuffer;
function Connected: Boolean; virtual;
constructor Create(AOwner: TComponent); override;
Descendant classes should override this constructor to set default values such as Port, and other protocol specific options.
function CurrentReadBuffer: string;
The return value includes all data in the Indy buffer up to size of the internal buffer. Result may also be '' (empty string) if no data is present in the internal Indy buffer.
destructor Destroy; override;
procedure Disconnect; virtual;
Disconnect triggers a hsDisconnecting status notification message prior to calling DisconnectSocket. When needed, Disconnect also frees the IOHandler. Finally, Disconnect triggers the OnDisconnected event handler and a hsDisconnected status notification message.
procedure DisconnectSocket; virtual;
DisconnectSocket is used when an error has occurred in a protocol handler and a guaranteed disconnect is needed.
procedure FlushWriteBuffer(const AByteCount: Integer = -1);
ABytes indicates the threshold value for the number of bytes that should be removed from the Indy buffer and sent to the peer socket connection. The default value (-1) forces all data in the Indy buffer to be written to the peer, and the write buffer is cleared using ClearWriteBuffer. This is also the case when the buffer is smaller than the threshold value in ABytes. Otherwise, the number of bytes in ABytes is removed from the Indy buffer and sent to the peer.
procedure GetInternalResponse;
The initial response line is expected to contain the 3-digit response code and text. Additional response lines are read when the initial response is a continuation response line, and continues until the terminal response or a blank line is received. All response lines are added to LastCmdResult.
function GetResponse(const AAllowedResponses: array of SmallInt): SmallInt; virtual; overload; function GetResponse(const AAllowedResponse: SmallInt): SmallInt; overload;
Use LastCmdResult to access the full text or numeric response number for the most recent response message, or multiple response messages.
GetResponse sets ResultNo to the three-digit numeric value from the most recent response message in LastCmdResult.
Finally, GetResponse calls CheckResponse using the values in ResultNo and AAllowedResponses to determine if the numeric response code is one of the numeric values allowed for the protocol action.
function GetResponse(const AAllowedResponses: array of SmallInt): SmallInt; virtual; overload; function GetResponse(const AAllowedResponse: SmallInt): SmallInt; overload;
Use LastCmdResult to access the full text or numeric response number for the most recent response message, or multiple response messages.
GetResponse sets ResultNo to the three-digit numeric value from the most recent response message in LastCmdResult.
Finally, GetResponse calls CheckResponse using the values in ResultNo and AAllowedResponses to determine if the numeric response code is one of the numeric values allowed for the protocol action.
function InputLn(const AMask: String = ''; AEcho: Boolean = True; ATabWidth: Integer = 8; AMaxLineLength: Integer = -1): String;
InputLn is useful when obtaining data from a user such as username, passwords, and commands.
procedure OpenWriteBuffer(const AThreshhold: Integer = -1);
AThreshold indicates the number of bytes that can accumulate in the Indy write buffer prior to using FlushWriteBuffer. The write buffer threshold is used to provide optimium data transfer without creating massive in memory buffers, or requiring the caller to periodically flush the buffer. When the write buffer size exceeds the threshold value, the connection will send a packet containing buffered data. The default value of AThreshold (-1) indicates that write buffering should be used for the entire write buffer. FlushWriteBuffer may also use a threshold value to determine the data packet size commited to the peer socket connection from the Indy internal buffer.
Use OpenWriteBuffer in a try...except block, like the following:
OpenWriteBuffer; try; WriteStream(AStream); // Close the write buffer and have Indy now transmit it CloseWriteBuffer; except // Clear what we had buffered, and disable write buffering CancelWriteBuffer; // Re-raise the exception so it is not masked raise; end;
procedure RaiseExceptionForLastCmdResult; virtual; overload;
When the TClassIdException variant is used, an instance of the exception class is raised using the text specified in LastCmdResult. The default implementation raises an EIdProtocolReplyError exception using the numeric and text values in LastCmdResult.
RaiseExceptionForLastCmdResult is used when GetResponse validates the numeric codes and messages permitted in the protocol response message.
procedure RaiseExceptionForLastCmdResult(AException: TClassIdException); virtual; overload;
When the TClassIdException variant is used, an instance of the exception class is raised using the text specified in LastCmdResult. The default implementation raises an EIdProtocolReplyError exception using the numeric and text values in LastCmdResult.
RaiseExceptionForLastCmdResult is used when GetResponse validates the numeric codes and messages permitted in the protocol response message.
procedure ReadBuffer(var ABuffer; const AByteCount: Longint);
ReadBuffer calls ReadFromStack to insure that the Indy read buffer contains at least the number of bytes specified in AByteCount. ReadBuffer calls CheckForDisconnect to insure that the socket connection has not been closed. ReadBuffer removes the number of bytes specified from the internal TIdManagedBuffer.
function ReadCardinal(const AConvert: boolean = true): Cardinal;
function ReadChar: Char;
ReadChar is used in InputLn to allow handling of values read from the connection on a character-by-character basis.
function ReadFromStack(const ARaiseExceptionIfDisconnected: Boolean = True; ATimeout: Integer = IdTimeoutDefault; const ARaiseExceptionOnTimeout: Boolean = True): Integer; virtual;
ATimeout indicates the number of milliseconds to wait for the IOHandler to become readable prior to reading data. When ATimeout contains the value IdTimeoutDefault, ReadTimeout will be used as the timeout value when it is non-zero. Otherwise, IdTimeoutInfinite is used as the timeout value. If a timeout occurs, an EIdReadTimeout exception will be raised when ARaiseExceptionOnTimeout is True. Otherwise ReadFromStack performs no additional processing, and uses -1 as the return value for the method.
ReadFromStack calls CheckForDisconnect using the value specifed in ARaiseExceptionIfDisconnected to determine if an exception is raised when the connection is closed. If the socket is not Connected, ReadFromStack will exit from the method.
ReadFromStack uses IOHandler to determine when the connection is readable, and to receive data from the input source. ReadFromStack updates ClosedGracefully indicating when all data has been read from the stack prior to closing the connection, and calls TIdStack.CheckForSocketError to determine if the connection closed abnormally.
When ClosedGracefully is False, the protocol stack is used to check for an Id_WSAESHUTDOWN error and allows the socket to disconnect when the error is detected. If the Indy read buffer contains no unread data, the Id_WSAESHUTDOWN exception is re-raised using the protocol stack handler.
ReadFromStack provides support for TIdConnectionIntercept by calling the Receive handler for the Intercept when Enabled. ReadFromStack also performs 8-bit to 7-bit character translations when ASCIIFilter is True.
Finally, ReadFromStack moves data read from the input source to the internal Indy buffer, and sets the return value to the number of bytes handled by the operation.
ReadFromStack can be a time intensive operation due to network contention and the nature of blocking sockets. ReadFromStack should be the only location where data is read from the protocol stack.
function ReadInteger(const AConvert: boolean = true): Integer;
ReadInteger uses ReadBuffer to read and extract the integer value from the Indy buffer. ReadInteger uses the WSNToHL method from TIdStackWinsock to convert the integer value from Internet byte-order to Intel byte-order.
function ReadLn(ATerminator: string = LF; const ATimeout: Integer = IdTimeoutDefault; AMaxLineLength: Integer = -1): string; virtual;
The optional ATerminator parameter indicates the end-of-line symbol for the particular protocol. If data is expected, and you do not need a custom end-of-line symbol, you can use the default ATerminator value (#0). ATerminator values include:
If there is no terminator (ATerminator) in the buffer, ReadLn will read more bytes from the TCP stack through the ReadFromStack method.
Use a custom time-out (ATimeout) value to change the number of milliseconds to wait for a response from the peer connection before a time-out occurs. The default value for ATimeout is IdTimeoutInfinite. See IdGlobal.pas for more information on constant timeout values.
ReadLn will return an empty string ('') if the peer connection is prematurely closed or a time-out occurs. When a timeout condition occurs in ReadLn, the ReadLnTimedOut property is set to True.
function ReadLnWait(AFailCount: Integer = MaxInt): string;
If there is no guarantee that data will be available, or a specific line delimiter is required, use ReadLn to retrieve data from the connection.
ReadLnWait calls ReadLn with the default delimiter and timeout values.
function ReadSmallInt(const AConvert: boolean = true): SmallInt;
AConvert indicates that the protocol stack WSNToHs method should be used to convert the numeric value from Network byte-order to Host-specific byte-order.
procedure ReadStream(AStream: TStream; AByteCount: LongInt = -1; const AReadUntilDisconnect: boolean = false);
AByteCount indicates the number of bytes to be read from the Indy buffer, or -1 if all bytes in the Indy buffer should be included. When AByteCount contains the number of bytes to be read, it is used to increase the size of AStream by the given number of bytes. This reduces memory or disk allocations to a single operation.
AReadUntilDisconnected indicates that data should be read from the protocol stack until the component is disconnected. When AReadUntilDisconnected is True, bytes are read from the protocol stack and written to AStream until Connected is False.
Note: When AByteCount is -1, and AReadUntilDisconnected is False, it is assumed that the first 4-bytes in the Indy buffer contains the length of buffered data in Internet format. ReadStream uses ReadInteger to convert the value to Intel byte-order prior to reading the remaining data from the Indy buffer.
function ReadString(const ABytes: Integer): string;
ReadString delays until the number of bytes in ABytes is available in the Indy read buffer. If the number of bytes is not known, use ReadLn or ReadLnWait.
procedure ReadStrings(var AValue: TStrings; AReadLinesCount: Integer = -1);
AReadLinesCount is the number of lines expected from the TCP connection, or -1 when the connection will contain an Integer that indicates the number of lines to be read. ReadStrings calls ReadInteger to get the line count when AReadLinesCount contains -1.
ReadStrings repetitively calls ReadLn until the number of expected lines has been read from the TCP connection.
Use LastCmdResult to access the numeric and text portions of the response for the command.
function SendCmd(const AOut: string; const AResponse: SmallInt = -1): SmallInt; overload; function SendCmd(const AOut: string; const AResponse: Array of SmallInt): SmallInt; virtual; overload;
Use LastCmdResult to access the numeric and text portions of the response for the command.
function WaitFor(const AString: string): string;
WaitFor calls CheckForDisconnect to detect when the connection is closed.
procedure Write(const AOut: string); virtual;
Write calls WriteBuffer to perform output from the buffer.
Write does not add an End-Of-Line sequence to the output buffer.
procedure WriteBuffer(const ABuffer; AByteCount: Longint; const AWriteNow: Boolean = False);
ABuffer is the TIdBuffer that contains data to be affected by WriteBuffer.
AByteCount is the number of bytes in the buffer to be affected by WriteBuffer.
When AWriteNow is True, write buffering will be ignored and ABuffer will be transmitted to the peer without updating the internal Indy write buffer. Note: If this is done after a call to OpenWriteBuffer, ABuffer will be transmitted before/in the middle of any data in the Indy internal write buffer.
Call OpenWriteBuffer to initiate use of Indy internal write buffering operations.
Call CancelWriteBuffer or CloseWriteBuffer to interrupt use of the internal Indy write buffer.
Call FlushWriteBuffer to force unsent data in the Indy internal write buffer to be sent to the peer connection.
Call ClearWriteBuffer to remove any unsent data in the Indy internal write buffer.
procedure WriteCardinal(AValue: Cardinal; const AConvert: Boolean = True);
Use ReadCardinal to read a 32-bit unsigned value from the peer connection.
function WriteFile(const AFile: String; const AEnableTransferFile: Boolean = False): Cardinal; virtual;
When AEnableTransferFile is True, Windows NT and Windows 2000 server can increase the efficiency of tile transfer operations, but cannot support TIdIntercept or progress indicators. AEnableTransferFile has no effect on Windows 95 and Windows 98.
Otherwise, WriteFile calls WriteStream using a TFileStream for the file specified in AFile to perform write operations over the connection.
WriteFile can raise a EIdFileNotFound exception when AFile does not exist on the local file system.
procedure WriteHeader(AHeader: TStrings);
WriteHeader calls WriteLn for each header item in axHeader. An additional blank line is written to the connection at the end of the header list.
procedure WriteInteger(AValue: Integer; const AConvert: Boolean = True);
AValue is the integer value to send to the peer connection.
AConvert indicates that the integer in AValue should be converted from local host byte-order to Internet byte-order. When AConvertis True, the protcol stack method WSHToNl is called to convert the binary integer value.
WriteInteger calls WriteBuffer to send AValue to the peer connection.
procedure WriteLn(const AOut: string = ''); virtual;
procedure WriteRFCReply(AReply: TIdRFCReply);
procedure WriteRFCStrings(AStrings: TStrings);
procedure WriteSmallInt(AValue: SmallInt; const AConvert: Boolean = True);
When AConvert is True, the value specified in AValue is converted to Internet byte-order using the prtocol stack method WSHToNs.
WriteSmallInt calls WriteBuffer to send the SmallInt value to the peer connection.
procedure WriteStream(AStream: TStream; const AAll: Boolean = True; const AWriteByteCount: Boolean = False; const ASize: Integer = 0); virtual;
AAll indicates that the stream should be positioned to the stream origin prior to sending stream data.
AWriteByteCount indicates that the Integer value containing the size of the stream should be written to the peer connection prior to the stream data. When AAll is true, this value reflects the size of the entire stream. When AAll is False, this value indicates the stream sixe from the current stream position to the end of the stream. When AWriteByteCount is True, WriteInteger is called to send the stream size to the peer connection.
WriteStream calls BeginWork with the work mode wmWrite and the size of the stream prior to sending stream data to the peer connection. The stream size is the value in AStream.Size, and is stored in a variable for subsequent use in the method. This reduces the overhead for TStream descendants where TStream.Seek is not efficient or practical.
AStream data is sent to the peer in blocks, where each block is read into a buffer that can contain up to SendBufferSize bytes. If a read from AStream results in a buffer with a length of 0, when the stream size and position indicate a non-zero value, an EIdNoDataToRead exception will be raised. Data read from AStream is sent on the connection using WriteBuffer with the current buffer contents and size.
WriteStream calls EndWork with the work mode wmWrite prior to exiting from the method.
procedure WriteStrings(AValue: TStrings; const AWriteLinesCount: Boolean = False);