Getting one character at a time from sockets

Steve Holden sholden at holdenweb.com
Tue Feb 6 18:34:55 EST 2001


"penman" <pen_man at my-deja.com> wrote in message
news:95q044$2f9$1 at nnrp1.deja.com...
> Using ordinary TCP/IP sockets with the socket module in Python, I need
> to get a single character at a time from the client; something
> like "talk" in unix. How could I do that? (should be platform
> independent if possible)
>
> recv(1) didn't work. It waited till the carriage return came in. (non-
> blocking didn't work either)
>
> Thanks in advance.
>
>
> Sent via Deja.com
> http://www.deja.com/
>
I suspect the problem here is the sending end: if you can convince the
transport layer to flush its buffers after getting one character from the
sending application then you should, in theory, be able to receive that
single byte (since the PSH flag should cause the receiving end to debuffer).

This isn't easy without closing the socket, however ... have you considered
revising your application architecture?

The Unix Socket FAQ has the following (and a lot more) to say about this
subject:

11. How can I force a socket to send the data in its buffer?

>From Richard Stevens (rstevens at noao.edu):

You can't force it. Period. TCP makes up its own mind as to when it can send
data. Now, normally when you call write() on a TCP socket, TCP will indeed
send a segment, but there's no guarantee and no way to force this. There are
lots of reasons why TCP will not send a segment: a closed window and the
Nagle algorithm are two things to come immediately to mind.

(Snipped suggestion from Andrew Gierth to use TCP_NODELAY)

Setting this only disables one of the many tests, the Nagle algorithm. But
if the original poster's problem is this, then setting this socket option
will help.

A quick glance at tcp_output() shows around 11 tests TCP has to make as to
whether to send a segment or not.

Now from Dr. Charles E. Campbell Jr. (cec at gryphon.gsfc.nasa.gov):

As you've surmised, I've never had any problem with disabling Nagle's
algorithm. Its basically a buffering method; there's a fixed overhead for
all packets, no matter how small. Hence, Nagle's algorithm collects small
packets together (no more than .2sec delay) and thereby reduces the amount
of overhead bytes being transferred. This approach works well for rcp, for
example: the .2 second delay isn't humanly noticeable, and multiple users
have their small packets more efficiently transferred. Helps in university
settings where most folks using the network are using standard tools such as
rcp and ftp, and programs such as telnet may use it, too.

However, Nagle's algorithm is pure havoc for real-time control and not much
better for keystroke interactive applications (control-C, anyone?). It has
seemed to me that the types of new programs using sockets that people write
usually do have problems with small packet delays. One way to bypass Nagle's
algorithm selectively is to use "out-of-band" messaging, but that is limited
in its content and has other effects (such as a loss of sequentiality) (by
the way, out-of-band is often used for that ctrl-C, too).

More from Vic:

So to sum it all up, if you are having trouble and need to flush the socket,
setting the TCP_NODELAY option will usually solve the problem. If it
doesn't, you will have to use out-of-band messaging, but according to
Andrew, "out-of-band data has its own problems, and I don't think it works
well as a solution to buffering delays (haven't tried it though). It is not
'expedited data' in the sense that exists in some other protocols; it is
transmitted in-stream, but with a pointer to indicate where it is."

etc., etc., ...

regards
 Steve




More information about the Python-list mailing list