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