Some remarks regarding the work with binary data (and this
package) in general:
Whatever you do, do not forget to switch the used
channels into binary mode, i.e. execute
``fconfigure <channel> -translation binary''.
Not doing this will produce all kind of strange
errors, even on unix machines, as the default translation mode
(``auto'') will not only convert CR LF into LF, but a single
CR as well!
If you want to use fileevents in combination with stacked
channels make sure that all channels in the stack are
nonblocking, i.e. execute
``fconfigure <channel> -blocking 0''
for them. Not doing so may cause the system to hang in a read/gets
procedure. This is independent of client or server. The reason is
that a transform uses internally 'Tcl_Read', even if the user
called 'gets', thus waiting for more information usually not
coming. Especially in a line oriented protocol. See the remarks
about buffering below too.
This version of Trf generates artificial 'readable'
events to flush out any information waiting in the various buffers
of the stack. For older versions a 'gets' or 'read' in a fileevent
script has to be wrapped into a loop reading data until exhaustion
([gets <channel> line] <0).
Using transformation procedures (as in this package)
introduces an additional level of buffering because they are
permitted to buffer all characters they are unable to process
immediately. This may mess up especially
interprocess communication, a notoriously problematic field. A
not so improbable scenario would be the addition of encryption
to enhance security. Using a blockcipher here may lead to the
following problem (a line-oriented protocol is assumed):
The solution here would be the usage of a blockcipher in CFB
mode and shift = 1 or that of a stream cipher, as both of
these would encrypt single characters without buffering.
Data compression is another good candidate for such a situation.
Because of this I decided to include the number of characters
buffered by a certain transformation in its description.
The sender produces a line and writes it into the channel,
waiting for a response from the receiver afterward.
The channel system invokes the blockcipher to encrypt
the line, but not all characters are encrypted due to
the length of the line not being a multiple of the
blocksize. Especially the EOL-character is neither
encrypted, nor transmitted.
The receiver decrypts the blocks it got, then waits
for the EOL character.