I'm using twisted python to make a simple SSH server on a custom port. I create a Port object with port = reactor.listenTCP(_port, sshfactory)
, where _port is a variable that holds the integer of the port. I free up the port when shutting down the server with the commands port.loseConnection()
and port.connectionLost(reason=None)
. If I attempt to start the server, stop it, and start it again, I get the titular error 'Port' object has no attribute 'socket'
Edit: full error message:
Unhandled error in Deferred:
Traceback (most recent call last):
File "C:\Python27\lib\site-packages\twisted\internet\base.py", line 1175, in mainLoop
self.runUntilCurrent()
File "C:\Python27\lib\site-packages\twisted\internet\base.py", line 779, in runUntilCurrent
call.func(*call.args, **call.kw)
File "C:\Python27\lib\site-packages\twisted\internet\defer.py", line 238, in callback
self._startRunCallbacks(result)
File "C:\Python27\lib\site-packages\twisted\internet\defer.py", line 307, in _startRunCallbacks
self._runCallbacks()
--- <exception caught here> ---
File "C:\Python27\lib\site-packages\twisted\internet\defer.py", line 323, in _runCallbacks
self.result = callback(self.result, *args, **kw)
File "C:\Python27\lib\site-packages\twisted\internet\task.py", line 736, in <lambda>
d.addCallback(lambda ignored: callable(*args, **kw))
File "C:\Python27\lib\site-packages\twisted\internet\tcp.py", line 981, in connectionLost
self._closeSocket()
File "C:\Python27\lib\site-packages\twisted\internet\tcp.py", line 92, in _closeSocket
skt = self.socket
exceptions.AttributeError: 'Port' object has no attribute 'socket'
Edit2: stopListening code sample (Python 2.7):
stopListening sample.py
from twisted.cred import portal, checkers, credentials
from twisted.conch import error, avatar, recvline, interfaces as conchinterfaces
from twisted.conch.ssh import factory, userauth, connection, keys, session, common
from twisted.conch.insults import insults
from twisted.application import service, internet
from twisted.internet import reactor, protocol
from zope.interface import implements
import threading
import os
class SSHDemoProtocol(recvline.HistoricRecvLine):
def __init__(self, user):
self.user = user
def connectionMade(self):
recvline.HistoricRecvLine.connectionMade(self)
self.showPrompt()
def showPrompt(self):
self.terminal.write("$ ")
class SSHDemoRealm:
implements(portal.IRealm)
def requestAvatar(self, avatarId, mind, *interfaces):
if conchinterfaces.IConchUser in interfaces:
return interfaces[0], SSHDemoAvatar(avatarId), lambda: None
else:
raise Exception("No supported interfaces found.")
def getRSAKeys():
if not (os.path.exists('public.key') and os.path.exists('private.key')):
# generate a RSA keypair
print("Generating RSA keypair...")
from Crypto.PublicKey import RSA
KEY_LENGTH = 1024
rsaKey = RSA.generate(KEY_LENGTH, common.entropy.get_bytes)
publicKeyString = keys.makePublicKeyString(rsaKey)
privateKeyString = keys.makePrivateKeyString(rsaKey)
# save keys for next time
file('public.key', 'w+b').write(publicKeyString)
file('private.key', 'w+b').write(privateKeyString)
print("done.")
else:
publicKeyString = file('public.key').read()
privateKeyString = file('private.key').read()
return publicKeyString, privateKeyString
def launchServer():
_port = 4564
password = 'password'
sshFactory = factory.SSHFactory()
sshFactory.portal = portal.Portal(SSHDemoRealm())
users = {'user': password}
sshFactory.portal.registerChecker(
checkers.InMemoryUsernamePasswordDatabaseDontUse(**users))
pubKeyString, privKeyString = getRSAKeys()
sshFactory.publicKeys = {
'ssh-rsa': keys.getPublicKeyString(data=pubKeyString)}
sshFactory.privateKeys = {
'ssh-rsa': keys.getPrivateKeyObject(data=privKeyString)}
global port
port = reactor.listenTCP(_port, sshFactory)
reactor.addSystemEventTrigger('before', 'shutdown', stopServer)
reactor.run(installSignalHandlers=False)
def startServer():
thread = threading.Thread(target=launchServer)
thread.start()
def stopServer():
global port
port.stopListening()
reactor.stop()
reactor.crash()
startServer()
stopServer()
startServer()
traceback:
>>> Exception in thread Thread-2:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 552, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 505, in run
self.__target(*self.__args, **self.__kwargs)
File "/home/paul/Desktop/Down2Home/stopListening sample.py", line 62, in launchServer
port = reactor.listenTCP(_port, sshFactory)
File "/usr/local/lib/python2.7/dist-packages/Twisted-9.0.0-py2.7-linux-x86_64.egg/twisted/internet/posixbase.py", line 355, in listenTCP
p.startListening()
File "/usr/local/lib/python2.7/dist-packages/Twisted-9.0.0-py2.7-linux-x86_64.egg/twisted/internet/tcp.py", line 855, in startListening
raise CannotListenError, (self.interface, self.port, le)
CannotListenError: Couldn't listen on any:4564: [Errno 98] Address already in use.