06 July 2007

Recently, I was writing a test script using telnetlib of Python. However, the family of read functions can be really confusing, say, what is lazy read, what is eager read? Neither Python document nor google gives many clue. Fortunately, the library is open-source and very easy to follow. Here is what I got after reading the source.

How telnetlib works

To understand the meaning of each read function in the telnetlib, we need to understand how telnetlib works. First, telnetlib receives packets from internet using socket connections. Then, it stores the data into its raw queue. After that, the library cooks (parse/handle) the data according to telnet protocol, putting result into its cooked queue.

---------,      ,----------,      ,-----,      ,--------,      ,-----------,
 network |=====>|socket buf|=====>|raw-q|=====>|cooked-q|=====>|application|
---------`      `----------`      `-----`      `--------`      `-----------`
   |               |                 |              |               |
   |               |                 |              |               |
   |               |                 |              |---------------|
   |               |                 |               read_very_lazy |
   |               |                 |                              |
   |               |                 |------------------------------|
   |               |                          read_lazy             |
   |               |                                                |
   |               |------------------------------------------------|
   |                          read_very_eager/read_eager            |
   |                                                                |
   |----------------------------------------------------------------|
   |    read_until/read_all/read_some/expect                        |

Meaning of read functions

read_very_lazy
read cooked data from cooked queque
read_lazy
If there is data in raw queue, read it. Then, read from cooked queue.
read_eager
Read from socket buffer using non-blocking mode1 first. Then, read from cooked queue.
read_very_eager
Similar with read_eager. The difference is that read_eager returns so long as it read something from cooked queue while read_very_eager tries to read as much as possible.
others
The remaining read functions basically block until they received designated data.

Footnotes:

1

This "non-blocking" is about normal data, as explained in Python document: "Do not block unless in the midst of an IAC sequence."



blog comments powered by Disqus