[Twisted-Python] using ClientFactory from within a server

Greg greg at digitalinfo.net
Sun Sep 28 21:30:33 EDT 2003

I am having trouble using ClientFactory to communicate from within a server. 
Specifically, I can't figure out the proper way to exit from the client 

Included is some example code illustrating the problem I am having. It is the 
simple echo server example, but when someone sends some text to the server, I 
am trying to talk to an SMTP server to send an email. This is just an example 
(there are probably better ways to fire off an email), but you get the idea. 
The client code never "exits" and if I try to use reactor.stop() it causes a 

So how do I properly exit from this client code, or (being new to twisted) am 
I going about this in the entirely wrong way? Thanks.

#!/usr/bin/env python

from twisted.internet import reactor
from twisted.internet.protocol import Protocol, ClientFactory, ServerFactory
import sys

class Echo(Protocol):
	"""This is just about the simplest possible protocol"""
	def dataReceived(self, data):
		"As soon as any data is received, write it back."
		factory2 = MySMTPClientFactory()
		host = 'localhost'
		port = 25
		reactor.connectTCP(host, port, factory2)

		print "Returned from sending email"
		# ^ Never gets to this point
class MySMTP(Protocol):
	def dataReceived(self, data):
			sys.stdout.write('Server said: ' + data)
			if data[:3] == "220":
				self.transport.write("helo foo.com\n")
				self.stage = 1
			if data[:3] == "250":
				if self.stage == 1:
					self.transport.write("MAIL FROM:<greg at foo.com>\n")
					self.stage = 2
				elif self.stage == 2:
					self.transport.write("RCPT TO:<greg at foo.com>\n")
					self.stage = 3
				elif self.stage == 3:
					self.stage = 4
				elif self.stage == 4:
					# ^ This causes a traceback
			if data[:3] == "354":
				# Ready to send actual email
				self.transport.write("This is a test email\n.\n")

class MySMTPClientFactory(ClientFactory):
	def startedConnection(self, connector):
		print 'Started to connect.'
	def buildProtocol(self, addr):
		print 'Connected.'
		return MySMTP()
	def clientConnectionLost(self, connector, reason):
		print 'Lost connection.  Reason:', reason
		# ^ Causes a traceback here too
	def clientConnectionFailed(self, connector, reason):
		print 'Connection failed. Reason:', reason

def main():
	"""This runs the protocol on port 8000"""
	factory = ServerFactory()
	factory.protocol = Echo

# this only runs if the module was *not* imported
if __name__ == '__main__':

More information about the Twisted-Python mailing list