newbie socket/thread question
Ken
khirmint at hotmail.com
Fri Mar 8 16:11:00 EST 2002
Hey everyone..
I'm messing around with Python, trying to learn the language, by
building a simple network chat program that uses threads and sockets.
I'm trying to set it up so that if the server receives a keyboard
interupt from console, it'll shut everything down. Which seems to work
fine for the most part. The problem is that after a user connects and
the server is stopped, the server cannot start up again right away. It
gets the error:
socket.error: (48, 'Address already in use')
This only happens after a user has connected, though.
Can anyone give me an idea of what I'm doing wrong?
Here's the code that I'm using: (keep in mind that I'm just learning the
language and that program itself is incomplete)
#! /usr/bin/env python
#
# Globals
#
CHATPORT = 43278
userlist = []
#
# Imports
#
from socket import socket, gethostbyname, AF_INET, SOCK_STREAM
from threading import Lock, Thread, Event
from time import sleep
from signal import signal, SIGINT
#
# User
#
class User ( Thread ):
"Handles incoming and outgoing communications to a user"
def __init__ ( self, conn, addr, goevent ):
print "Initializing user.."
Thread.__init__ ( self )
self.conn = conn
self.addr = addr
self.goevent = goevent;
def run ( self ):
while self.goevent.isSet ():
try:
data = conn.recv ( 1024 )
print "Got data..: " + data
except:
sleep ( 3 )
pass
def terminate ( self ):
print "Terminating " + self.addr[0]
self.conn.close ()
#
# MasterListener
#
class SocketListener ( Thread ):
"Waits for connections to be recieved and hands new connections off \
to the child handler"
def __init__ ( self, goevent, port ):
Thread.__init__ ( self )
self.goevent = goevent
self.hostip = gethostbyname ( 'localhost' )
self.port = port
# setup the socket
self.mainsocket = socket ( AF_INET, SOCK_STREAM )
self.mainsocket.bind ( (self.hostip, self.port) )
self.mainsocket.listen ( 1 )
self.mainsocket.setblocking ( 0 )
def run ( self ):
print "Daemon started and awaiting connections.."
while self.goevent.isSet ():
try:
conn, addr = self.mainsocket.accept ()
print "Connected by", addr
print "Connection received.."
# start up a user thread to handle the new comer
newuser = User ( conn, addr, self.goevent )
newuser.start ()
userlist.append ( newuser )
except:
sleep ( 1 )
# clean up
print "Closing user connections.."
for user in userlist:
user.terminate ()
print " user connections closed."
print "Closing main socket.."
self.mainsocket.close ()
print "Socket Listener Terminated"
class MasterLoop:
"Handles the startup of the daemon, starts network functionality, etc"
def __init__ ( self ):
self.mastergoevent = Event ()
self.socketlistener = SocketListener ( self.mastergoevent, CHATPORT )
signal ( SIGINT, self.sigint_handler )
def beginExecute ( self ):
self.mastergoevent.set ()
self.socketlistener.start ()
# loop endlessly until told to terminate
while self.mastergoevent.isSet ():
sleep ( 1 )
def endExecute ( self ):
self.mastergoevent.clear ()
def sigint_handler ( self, frame, frameobj ):
print "\nAttempting to shutdown daemon.. please wait.."
self.endExecute ()
if __name__ == '__main__':
"Simple chat server"
maincontrol = MasterLoop ()
maincontrol.beginExecute ()
More information about the Python-list
mailing list