[Pythonmac-SIG] Problem with Mac Python 2.0: Tk and sockets

Russell E Owen owen@astro.washington.edu
Fri, 3 Nov 2000 11:09:55 -0800


I have a simple telnet client that uses Tk and file events (part of a 
bigger project). It works fine in Mac Python 1.5.2 but not 2.0. Can 
anybody confirm this and does anybody have any ideas. I have appended 
the code. The symptoms of the problems in Python 2.0 are:

- the Python client will send data successfully, but it seems to 
spend all of my free CPU cycles doing it. The reason I know I can 
send data is I have an application on the host computer that 
retransmits received data. If I connect a separate normal telnet 
client (NiftyTelnet) I can see any data that my Python client sends. 
When I do this, I see the data, but only if I switch out of Python 
Interpreter (bringing any other application in front).

- the Python client will never display any returned data, period. 
It's as if file events aren't working. I suppose it may have 
something to do with spare CPU cycles, but I can keep sending data as 
much as I like, I just never see any of it back.

-- Russell

##### test code, cut here #####
# to use:
# - save as a file
# - edit the host name (see "host =" line near the end)
# - drop the file onto Python Interpreter
#
# It should work fine in Mac Python 1.5.2
# but I can't get it to work in Mac Python 2.0

import socket, Tkinter, sys

class MyClient:
	__IAC  = chr(255)	# Interpret as command
	__DONT = chr(254)
	__DO   = chr(253)
	__WONT = chr(252)
	__WILL = chr(251)

	def __init__ (self, inText, host, showNegotiation=0):
		self.inText = inText
		self.host = host
		self.showNegotiation = showNegotiation
		self.nnegotiations = 0
		self.__iac = 0
		self.__opt = ''
		self.__optText = ''
		self.__cleanchars = ''
		self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
		try:
			self.sock.connect((self.host,23))
			Tkinter.tkinter.createfilehandler(self.sock,
				Tkinter.tkinter.READABLE, self.__readSocket)
		except socket.error, e:
			print "connect failed:", e
		self.inText.bind('<KeyPress-Return>', self.__writeSocket)

	def __readSocket (self, sock, flags):
		"""reads the socket,
			replies to negotiation requests
			and prints other data (omitting '\r' and '\0')"""
		data = sock.recv(1024)
		if not data:
			print "connection closed by foreign host"
			Tkinter.tkinter.deletefilehandler(self.sock)
		for c in data:
			if self.__opt:
				self.nnegotiations = self.nnegotiations + 1
				if self.nnegotiations > 30:
					print "no more negotations"
				else:
					sock.send(self.__opt + c)
				if self.showNegotiation:
					print self.__optText, c
				self.__opt = ''
				self.__optText = ""
			elif self.__iac:
				self.__iac = 0
				if c == self.__iac:
					self.__cleanchars = 
self.__cleanchars + c
				elif c in (MyClient.__DO, MyClient.__DONT):
					self.__opt = MyClient.__IAC + 
MyClient.__WONT
					if c == MyClient.__DO:
						self.__optText = "DO"
					else:
						self.__optText = "DONT"
				elif c in (MyClient.__WILL, MyClient.__WONT):
					self.__opt = MyClient.__IAC + 
MyClient.__DONT
					if c == MyClient.__WILL:
						self.__optText = "WILL"
					else:
						self.__optText = "WONT"
			elif c == MyClient.__IAC:
				self.__iac = 1
			elif c == '\r':
				pass
			elif c == '\0':
				pass
			else:
				self.__cleanchars = self.__cleanchars + c
		print self.__cleanchars
		self.__cleanchars = ''

	def __writeSocket (self, evt):
		try:
			self.sock.send (inText.get() + '\r')
		except socket.error, e:
			print "send failed:", e
		inText.delete(0,Tkinter.END)

host = 'tccdev'

root = Tkinter.Tk()
mainFrame = Tkinter.Frame(root)
aLabel = Tkinter.Label(mainFrame,
	text="Type text to send, then <return> to send it")
aLabel.pack(fill=Tkinter.X, expand=Tkinter.YES)
inText = Tkinter.Entry(mainFrame, takefocus=1)
inText.pack(fill=Tkinter.X, expand=Tkinter.YES)
mainFrame.pack()
inText.focus_set()

aClient = MyClient (inText, host, showNegotiation=1)

root.mainloop()