blob: 6b249e8db416f26d7f2e597022b10ed9a1578319 [file] [log] [blame]
Guido van Rossumb9b50eb1997-12-24 21:07:04 +00001"""TELNET client class.
2
3Based on RFC 854: TELNET Protocol Specification, by J. Postel and
4J. Reynolds
5
6Example:
7
8>>> from telnetlib import Telnet
9>>> tn = Telnet('www.python.org', 79) # connect to finger port
10>>> tn.write('guido\r\n')
11>>> print tn.read_all()
12Login Name TTY Idle When Where
13guido Guido van Rossum pts/2 <Dec 2 11:10> snag.cnri.reston..
Tim Petersb90f89a2001-01-15 03:26:36 +000014
Guido van Rossumb9b50eb1997-12-24 21:07:04 +000015>>>
16
17Note that read_all() won't read until eof -- it just reads some data
18-- but it guarantees to read at least one byte unless EOF is hit.
19
20It is possible to pass a Telnet object to select.select() in order to
21wait until more data is available. Note that in this case,
22read_eager() may return '' even if there was data on the socket,
23because the protocol negotiation may have eaten the data. This is why
24EOFError is needed in some cases to distinguish between "no data" and
25"connection closed" (since the socket also appears ready for reading
26when it is closed).
27
28Bugs:
29- may hang when connection is slow in the middle of an IAC sequence
30
31To do:
32- option negotiation
Guido van Rossumccb5ec61997-12-24 22:24:19 +000033- timeout should be intrinsic to the connection object instead of an
34 option on one of the read calls only
Guido van Rossumb9b50eb1997-12-24 21:07:04 +000035
36"""
37
38
39# Imported modules
Guido van Rossumccb5ec61997-12-24 22:24:19 +000040import sys
Guido van Rossumb9b50eb1997-12-24 21:07:04 +000041import socket
42import select
Guido van Rossumb9b50eb1997-12-24 21:07:04 +000043
Skip Montanaro40fc1602001-03-01 04:27:19 +000044__all__ = ["Telnet"]
45
Guido van Rossumb9b50eb1997-12-24 21:07:04 +000046# Tunable parameters
47DEBUGLEVEL = 0
48
49# Telnet protocol defaults
50TELNET_PORT = 23
51
52# Telnet protocol characters (don't change)
53IAC = chr(255) # "Interpret As Command"
54DONT = chr(254)
55DO = chr(253)
56WONT = chr(252)
57WILL = chr(251)
58theNULL = chr(0)
59
60
61class Telnet:
62
63 """Telnet interface class.
64
65 An instance of this class represents a connection to a telnet
66 server. The instance is initially not connected; the open()
67 method must be used to establish a connection. Alternatively, the
68 host name and optional port number can be passed to the
69 constructor, too.
70
71 Don't try to reopen an already connected instance.
72
73 This class has many read_*() methods. Note that some of them
74 raise EOFError when the end of the connection is read, because
75 they can return an empty string for other reasons. See the
76 individual doc strings.
77
78 read_until(expected, [timeout])
79 Read until the expected string has been seen, or a timeout is
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000080 hit (default is no timeout); may block.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +000081
82 read_all()
83 Read all data until EOF; may block.
84
85 read_some()
86 Read at least one byte or EOF; may block.
87
88 read_very_eager()
89 Read all data available already queued or on the socket,
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000090 without blocking.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +000091
92 read_eager()
93 Read either data already queued or some data available on the
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000094 socket, without blocking.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +000095
96 read_lazy()
97 Read all data in the raw queue (processing it first), without
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000098 doing any socket I/O.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +000099
100 read_very_lazy()
101 Reads all data in the cooked queue, without doing any socket
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000102 I/O.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000103
104 """
105
106 def __init__(self, host=None, port=0):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000107 """Constructor.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000108
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000109 When called without arguments, create an unconnected instance.
110 With a hostname argument, it connects the instance; a port
111 number is optional.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000112
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000113 """
114 self.debuglevel = DEBUGLEVEL
115 self.host = host
116 self.port = port
117 self.sock = None
118 self.rawq = ''
119 self.irawq = 0
120 self.cookedq = ''
121 self.eof = 0
122 if host:
123 self.open(host, port)
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000124
125 def open(self, host, port=0):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000126 """Connect to a host.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000127
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000128 The optional second argument is the port number, which
129 defaults to the standard telnet port (23).
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000130
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000131 Don't try to reopen an already connected instance.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000132
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000133 """
134 self.eof = 0
135 if not port:
136 port = TELNET_PORT
137 self.host = host
138 self.port = port
139 self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
140 self.sock.connect((self.host, self.port))
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000141
142 def __del__(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000143 """Destructor -- close the connection."""
144 self.close()
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000145
146 def msg(self, msg, *args):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000147 """Print a debug message, when the debug level is > 0.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000148
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000149 If extra arguments are present, they are substituted in the
150 message using the standard string formatting operator.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000151
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000152 """
153 if self.debuglevel > 0:
154 print 'Telnet(%s,%d):' % (self.host, self.port),
155 if args:
156 print msg % args
157 else:
158 print msg
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000159
160 def set_debuglevel(self, debuglevel):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000161 """Set the debug level.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000162
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000163 The higher it is, the more debug output you get (on sys.stdout).
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000164
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000165 """
166 self.debuglevel = debuglevel
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000167
168 def close(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000169 """Close the connection."""
170 if self.sock:
171 self.sock.close()
172 self.sock = 0
173 self.eof = 1
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000174
175 def get_socket(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000176 """Return the socket object used internally."""
177 return self.sock
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000178
179 def fileno(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000180 """Return the fileno() of the socket object used internally."""
181 return self.sock.fileno()
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000182
183 def write(self, buffer):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000184 """Write a string to the socket, doubling any IAC characters.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000185
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000186 Can block if the connection is blocked. May raise
187 socket.error if the connection is closed.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000188
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000189 """
190 if IAC in buffer:
Eric S. Raymond6b8c5282001-02-09 07:10:12 +0000191 buffer = buffer.replace(IAC, IAC+IAC)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000192 self.msg("send %s", `buffer`)
193 self.sock.send(buffer)
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000194
195 def read_until(self, match, timeout=None):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000196 """Read until a given string is encountered or until timeout.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000197
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000198 When no match is found, return whatever is available instead,
199 possibly the empty string. Raise EOFError if the connection
200 is closed and no cooked data is available.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000201
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000202 """
203 n = len(match)
204 self.process_rawq()
Eric S. Raymond6b8c5282001-02-09 07:10:12 +0000205 i = self.cookedq.find(match)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000206 if i >= 0:
207 i = i+n
208 buf = self.cookedq[:i]
209 self.cookedq = self.cookedq[i:]
210 return buf
211 s_reply = ([self], [], [])
212 s_args = s_reply
213 if timeout is not None:
214 s_args = s_args + (timeout,)
215 while not self.eof and apply(select.select, s_args) == s_reply:
216 i = max(0, len(self.cookedq)-n)
217 self.fill_rawq()
218 self.process_rawq()
Eric S. Raymond6b8c5282001-02-09 07:10:12 +0000219 i = self.cookedq.find(match, i)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000220 if i >= 0:
221 i = i+n
222 buf = self.cookedq[:i]
223 self.cookedq = self.cookedq[i:]
224 return buf
225 return self.read_very_lazy()
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000226
227 def read_all(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000228 """Read all data until EOF; block until connection closed."""
229 self.process_rawq()
230 while not self.eof:
231 self.fill_rawq()
232 self.process_rawq()
233 buf = self.cookedq
234 self.cookedq = ''
235 return buf
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000236
237 def read_some(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000238 """Read at least one byte of cooked data unless EOF is hit.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000239
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000240 Return '' if EOF is hit. Block if no data is immediately
241 available.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000242
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000243 """
244 self.process_rawq()
245 while not self.cookedq and not self.eof:
246 self.fill_rawq()
247 self.process_rawq()
248 buf = self.cookedq
249 self.cookedq = ''
250 return buf
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000251
252 def read_very_eager(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000253 """Read everything that's possible without blocking in I/O (eager).
Tim Petersb90f89a2001-01-15 03:26:36 +0000254
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000255 Raise EOFError if connection closed and no cooked data
256 available. Return '' if no cooked data available otherwise.
257 Don't block unless in the midst of an IAC sequence.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000258
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000259 """
260 self.process_rawq()
261 while not self.eof and self.sock_avail():
262 self.fill_rawq()
263 self.process_rawq()
264 return self.read_very_lazy()
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000265
266 def read_eager(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000267 """Read readily available data.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000268
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000269 Raise EOFError if connection closed and no cooked data
270 available. Return '' if no cooked data available otherwise.
271 Don't block unless in the midst of an IAC sequence.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000272
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000273 """
274 self.process_rawq()
275 while not self.cookedq and not self.eof and self.sock_avail():
276 self.fill_rawq()
277 self.process_rawq()
278 return self.read_very_lazy()
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000279
280 def read_lazy(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000281 """Process and return data that's already in the queues (lazy).
Tim Petersb90f89a2001-01-15 03:26:36 +0000282
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000283 Raise EOFError if connection closed and no data available.
284 Return '' if no cooked data available otherwise. Don't block
285 unless in the midst of an IAC sequence.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000286
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000287 """
288 self.process_rawq()
289 return self.read_very_lazy()
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000290
291 def read_very_lazy(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000292 """Return any data available in the cooked queue (very lazy).
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000293
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000294 Raise EOFError if connection closed and no data available.
295 Return '' if no cooked data available otherwise. Don't block.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000296
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000297 """
298 buf = self.cookedq
299 self.cookedq = ''
300 if not buf and self.eof and not self.rawq:
301 raise EOFError, 'telnet connection closed'
302 return buf
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000303
304 def process_rawq(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000305 """Transfer from raw queue to cooked queue.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000306
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000307 Set self.eof when connection is closed. Don't block unless in
308 the midst of an IAC sequence.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000309
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000310 """
311 buf = ''
312 try:
313 while self.rawq:
314 c = self.rawq_getchar()
315 if c == theNULL:
316 continue
317 if c == "\021":
318 continue
319 if c != IAC:
320 buf = buf + c
321 continue
322 c = self.rawq_getchar()
323 if c == IAC:
324 buf = buf + c
325 elif c in (DO, DONT):
326 opt = self.rawq_getchar()
327 self.msg('IAC %s %d', c == DO and 'DO' or 'DONT', ord(c))
328 self.sock.send(IAC + WONT + opt)
329 elif c in (WILL, WONT):
330 opt = self.rawq_getchar()
331 self.msg('IAC %s %d',
332 c == WILL and 'WILL' or 'WONT', ord(c))
Guido van Rossum823eb4b2000-05-02 14:32:11 +0000333 self.sock.send(IAC + DONT + opt)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000334 else:
335 self.msg('IAC %s not recognized' % `c`)
336 except EOFError: # raised by self.rawq_getchar()
337 pass
338 self.cookedq = self.cookedq + buf
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000339
340 def rawq_getchar(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000341 """Get next char from raw queue.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000342
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000343 Block if no data is immediately available. Raise EOFError
344 when connection is closed.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000345
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000346 """
347 if not self.rawq:
348 self.fill_rawq()
349 if self.eof:
350 raise EOFError
351 c = self.rawq[self.irawq]
352 self.irawq = self.irawq + 1
353 if self.irawq >= len(self.rawq):
354 self.rawq = ''
355 self.irawq = 0
356 return c
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000357
358 def fill_rawq(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000359 """Fill raw queue from exactly one recv() system call.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000360
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000361 Block if no data is immediately available. Set self.eof when
362 connection is closed.
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000363
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000364 """
365 if self.irawq >= len(self.rawq):
366 self.rawq = ''
367 self.irawq = 0
368 # The buffer size should be fairly small so as to avoid quadratic
369 # behavior in process_rawq() above
370 buf = self.sock.recv(50)
371 self.msg("recv %s", `buf`)
372 self.eof = (not buf)
373 self.rawq = self.rawq + buf
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000374
375 def sock_avail(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000376 """Test whether data is available on the socket."""
377 return select.select([self], [], [], 0) == ([self], [], [])
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000378
379 def interact(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000380 """Interaction function, emulates a very dumb telnet client."""
Guido van Rossum82eae9e1998-12-23 23:04:17 +0000381 if sys.platform == "win32":
382 self.mt_interact()
383 return
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000384 while 1:
385 rfd, wfd, xfd = select.select([self, sys.stdin], [], [])
386 if self in rfd:
387 try:
388 text = self.read_eager()
389 except EOFError:
390 print '*** Connection closed by remote host ***'
391 break
392 if text:
393 sys.stdout.write(text)
394 sys.stdout.flush()
395 if sys.stdin in rfd:
396 line = sys.stdin.readline()
397 if not line:
398 break
399 self.write(line)
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000400
Guido van Rossum82eae9e1998-12-23 23:04:17 +0000401 def mt_interact(self):
402 """Multithreaded version of interact()."""
403 import thread
404 thread.start_new_thread(self.listener, ())
405 while 1:
406 line = sys.stdin.readline()
407 if not line:
408 break
409 self.write(line)
410
411 def listener(self):
412 """Helper for mt_interact() -- this executes in the other thread."""
413 while 1:
414 try:
415 data = self.read_eager()
416 except EOFError:
417 print '*** Connection closed by remote host ***'
418 return
419 if data:
420 sys.stdout.write(data)
421 else:
422 sys.stdout.flush()
423
Guido van Rossumccb5ec61997-12-24 22:24:19 +0000424 def expect(self, list, timeout=None):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000425 """Read until one from a list of a regular expressions matches.
Guido van Rossumccb5ec61997-12-24 22:24:19 +0000426
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000427 The first argument is a list of regular expressions, either
428 compiled (re.RegexObject instances) or uncompiled (strings).
429 The optional second argument is a timeout, in seconds; default
430 is no timeout.
Guido van Rossumccb5ec61997-12-24 22:24:19 +0000431
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000432 Return a tuple of three items: the index in the list of the
433 first regular expression that matches; the match object
434 returned; and the text read up till and including the match.
Guido van Rossumccb5ec61997-12-24 22:24:19 +0000435
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000436 If EOF is read and no text was read, raise EOFError.
437 Otherwise, when nothing matches, return (-1, None, text) where
438 text is the text received so far (may be the empty string if a
439 timeout happened).
Guido van Rossumccb5ec61997-12-24 22:24:19 +0000440
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000441 If a regular expression ends with a greedy match (e.g. '.*')
442 or if more than one expression can match the same input, the
443 results are undeterministic, and may depend on the I/O timing.
Guido van Rossumccb5ec61997-12-24 22:24:19 +0000444
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000445 """
446 re = None
447 list = list[:]
448 indices = range(len(list))
449 for i in indices:
450 if not hasattr(list[i], "search"):
451 if not re: import re
452 list[i] = re.compile(list[i])
453 while 1:
454 self.process_rawq()
455 for i in indices:
456 m = list[i].search(self.cookedq)
457 if m:
458 e = m.end()
459 text = self.cookedq[:e]
460 self.cookedq = self.cookedq[e:]
461 return (i, m, text)
462 if self.eof:
463 break
464 if timeout is not None:
465 r, w, x = select.select([self.fileno()], [], [], timeout)
466 if not r:
467 break
468 self.fill_rawq()
469 text = self.read_very_lazy()
470 if not text and self.eof:
471 raise EOFError
472 return (-1, None, text)
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000473
474
475def test():
476 """Test program for telnetlib.
477
478 Usage: python telnetlib.py [-d] ... [host [port]]
479
480 Default host is localhost; default port is 23.
481
482 """
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000483 debuglevel = 0
484 while sys.argv[1:] and sys.argv[1] == '-d':
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000485 debuglevel = debuglevel+1
486 del sys.argv[1]
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000487 host = 'localhost'
488 if sys.argv[1:]:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000489 host = sys.argv[1]
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000490 port = 0
491 if sys.argv[2:]:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000492 portstr = sys.argv[2]
493 try:
494 port = int(portstr)
495 except ValueError:
496 port = socket.getservbyname(portstr, 'tcp')
Guido van Rossumb9b50eb1997-12-24 21:07:04 +0000497 tn = Telnet()
498 tn.set_debuglevel(debuglevel)
499 tn.open(host, port)
500 tn.interact()
501 tn.close()
502
503if __name__ == '__main__':
504 test()