Getting one character at a time from sockets

David Bolen db3l at fitlinxx.com
Thu Feb 8 04:16:55 CET 2001


penman <pen_man at my-deja.com> writes:

> Thank you, Donn. But the problem is that I have to use ordinary telnet
> clients, such as CRT, Netterm, so let the users access to the server
> without any specialy programs.

It sounds like you aren't performing telnet options negotiation when
you get a connection.  At a minimum, even without that if you support
telnet clients you should process telnet IAC (hex 255) commands that
may show up in the stream from time to time or you may think that
you're getting bad data over the session.

By default, the telnet NVT (network virtual terminal) model is a line
buffered, half-duplex system.  So in the absence of other negotiation,
the clients are going to assume that they should only transmit upon
line termination, and also that they should perform local echoing of
characters being entered.  This works out nicely to permit telnet to
be used as a simple tool to connect to network servers that aren't
expecting it, but it does mean there's no character-at-a-time
transmission by default.

You can be sure you're in this mode if you are seeing what you type in
at your telnet client, but you haven't written code at your server to
explicitly echo received information back.

At a minimum, I would probably suggest having your server negotiate
the suppress-go-ahead and echo options (enabling both).  That means
that you should transmit a "DO SUPPRESS-GO-AHEAD" and a "WILL ECHO"
(unless you really want the client to handle local echo - not typical
in a full-duplex environment) over the stream during the startup of
the session.  The "DO" will request that the client transmit
character-by-character without needing GAs, and the latter will
indicate to the client that you are going to echo back what you
receive so the client will stop local echoing.  In response you should
expect to see a "WILL SUPPRESS-GO-AHEAD" and a "DO ECHO", which you'll
have to absorb and/or track with your options handling.

You might find the telnetlib.py library module to provide some very
basic examples of option processing, although it's geared towards
connecting to a server (not being a server) and doesn't really do full
options processing itself.

The real reference is in the RFCs - I'd probably suggest using:

    RFC854 (TELNET PROTOCOL SPECIFICATION)
    RFC855 (TELNET OPTION SPECIFICATIONS)
    RFC857 (TELNET ECHO OPTION)
    RFC858 (TELNET SUPPRESS GO AHEAD OPTION)

> I wonder why nobody ever had the need to recv 1 character "unbuffered"
> in Python.

I think you're generalizing too much.  Your issue is with the telnet
protocol, and not with raw socket communications.  recv() has no
impact on how a client may or may not be buffering network
communication - and note that it's the client doing the buffering
here, not your code.  And the reason the client is buffering it is
because the client is following the telnet protocol specification.  If
you were to write your own code that read a character from the
keyboard, did a send() on it, you would see the information come
through more immediately.

It is still true, however, that any TCP based system is subject to
various implementation details of TCP that may affect real time
delivery of data - by using TCP you are implicitly accepting that
fact.  Some items (e.g., the nagle algorithm) can impose several
hundred ms of latency even when no other buffering is going on at the
application layer.  It's part and parcel of the protocol - TCP makes
no guarantees about latency of delivery - just that the data will get
there intact and in order.

--
-- David
-- 
/-----------------------------------------------------------------------\
 \               David Bolen            \   E-mail: db3l at fitlinxx.com  /
  |             FitLinxx, Inc.            \  Phone: (203) 708-5192    |
 /  860 Canal Street, Stamford, CT  06902   \  Fax: (203) 316-5150     \
\-----------------------------------------------------------------------/



More information about the Python-list mailing list