Threaded server: what's wrong with this code?

Benjamin Han bhan at andrew.cmu.edu
Thu Dec 25 13:43:48 EST 2003


Ah - never mind. When reading SocketServer.py I found I should have used
ThreadingTCPServer instead of TCPServer (and I don't even need to create
threads myself!). Thank you for the reply though.

Ben

On Thu, 25 Dec 2003, Ahmed MOHAMED ALI wrote:

> Hi,
> Sorry for my bad english because i am French-speaking.
> The problem is in JMSocketThread.handle .When this function terminates its
> execution flow,the parameter "self.request"  is not longer valid.
> So the thread work with an invalid socket.For this reason,you got  the 'Bad
> file descriptor' error.
> To correct the problem here's the modified code.
>
> #---Modified JMHandler  class
>
> class JMHandler (SocketServer.BaseRequestHandler):
>      def handle (self):
>          print 'Client connected...'
>         threadEvent = Event()  # create an event to wait for the thread
>          JMSocketThread(self.request,threadEvent ).start() #  don't forget
> to pass the event parameter here
>          print 'Request handed off to a thread.'
>         threadEvent.wait()
>
> #---Modified JMSocketThread class
>
>  class JMSocketThread (threading.Thread):
>      def __init__ (self, theSocket):
>
> threading.Thread.__init__(self,target=self._myRun,args=[theSocket,theEvent])
> # don't forget to pass the event here
>      def _myRun (self,theSocket,theEvent): #don't forget to pass the event
> here too
>          global THREAD_COUNT
>          THREAD_COUNT+=1
>          print 'Threaded request started (%d)...'%THREAD_COUNT
>          input=''
>          while 1:
>              input += theSocket.recv(1024)
>              if len(input) and input[-1]=='\n': break
>          input=input.strip()
>
>          print 'Got input: \'%s\''%input
>          if input=='Is it you?':
>              theSocket.sendall('Yes honey.\n')
>
>          print 'Threaded request finished.'
>          THREAD_COUNT-=1
>          theEvent.set() # set the event here to tell the handler to exit
>
>
> Best regards,
> Ahmed
>
>
> "Fortepianissimo" <fortepianissimo at yahoo.com.tw> wrote in message
> news:ef08387c.0312241345.26a1430d at posting.google.com...
> > Below are three simple scripts: jmSocketLib.py contains library code
> > for socket server and client, server.py instantiates a server binding
> > to port 50000+ (grab the first available port), and client.py
> > simulates 1000 consecutive connection requests to the server (stress
> > test). The client searches from port 50000 for the server, and sends a
> > challenge "JM?" and expects to get a response "0_87" - otherwise
> > anything that happens to own a port 50000+ would be mistaken to be the
> > real server.
> >
> > The code:
> >
> > ---------- jmSocketLib.py ----------
> > #!/usr/bin/env python
> >
> > import SocketServer,socket,threading
> >
> > PORT_MIN=50000
> > PORT_MAX=50005
> >
> > THREAD_COUNT=0
> >
> > class JMSocketThread (threading.Thread):
> >     def __init__ (self, theSocket):
> >
> threading.Thread.__init__(self,target=self._myRun,args=[theSocket])
> >     def _myRun (self,theSocket):
> >         global THREAD_COUNT
> >         THREAD_COUNT+=1
> >         print 'Threaded request started (%d)...'%THREAD_COUNT
> >         input=''
> >         while 1:
> >             input += theSocket.recv(1024)
> >             if len(input) and input[-1]=='\n': break
> >         input=input.strip()
> >
> >         print 'Got input: \'%s\''%input
> >         if input=='Is it you?':
> >             theSocket.sendall('Yes honey.\n')
> >
> >         print 'Threaded request finished.'
> >         THREAD_COUNT-=1
> >
> >
> > class JMHandler (SocketServer.BaseRequestHandler):
> >     def handle (self):
> >         print 'Client connected...'
> >         JMSocketThread(self.request).start()
> >         print 'Request handed off to a thread.'
> >
> >
> > class JMServer (SocketServer.TCPServer):
> >     def __init__ (self):
> >         port=PORT_MIN
> >         while port<PORT_MAX:
> >             try:
> >                 SocketServer.TCPServer.__init__(self,('',port),JMHandler)
> >                 print 'Bound port %d'%port
> >                 break
> >             except:
> >                 port+=1
> >
> > class JMClient:
> >     def __init__ (self):
> >         port=PORT_MIN
> >
> >         while port<=PORT_MAX:
> >             try:
> >                 self.socket=socket.socket(socket.AF_INET,
> > socket.SOCK_STREAM)
> >                 self.socket.connect(('',port))
> >                 self.socket.sendall('Is it you?\n')
> >                 print 'Query sent...'
> >                 reply=''
> >                 while 1:
> >                     reply += self.socket.recv(1024)
> >                     if len(reply) and reply[-1]=='\n': break
> >                 reply=reply.strip()
> >
> >                 print 'Got reply: \'%s\''%reply
> >
> >                 if reply == 'Yes honey.':
> >                     print 'Found the server at port %d'%port
> >                     break
> >                 else: raise None
> >             except:
> >                 self.socket.close()
> >                 port+=1
> >
> >
> > ---------- server.py ----------
> > #!/usr/bin/env python
> >
> > from jmSocketLib import *
> >
> > if __name__ == '__main__':
> >     jmServer=JMServer()
> >     jmServer.serve_forever()
> >
> > ---------- client.py ----------
> > #!/usr/bin/env python
> >
> > from jmSocketLib import *
> >
> > if __name__ == '__main__':
> >     # stress test
> >     for i in range(1000):
> >         print i
> >         JMClient()
> >
> >
> >
> >
> > Now the problem is, every now and then I got this error from the
> > server side:
> >
> > ---- ERROR on server side ----
> > Client connected...
> > Threaded request started (1)...
> > Request handed off to a thread.
> > Got input: 'Is it you?'
> > Exception in thread Thread-125:
> > Traceback (most recent call last):
> >   File "/sw/src/root-python23-2.3.2-22/sw/lib/python2.3/threading.py",
> > line 436, in __bootstrap
> >     self.run()
> >   File "/sw/src/root-python23-2.3.2-22/sw/lib/python2.3/threading.py",
> > line 416, in run
> >     self.__target(*self.__args, **self.__kwargs)
> >   File "/Users/ben/temp/jmSocketLib.py", line 25, in _myRun
> >     theSocket.sendall('0_87\n')
> >   File "<string>", line 1, in sendall
> >   File "/sw/src/root-python23-2.3.2-22/sw/lib/python2.3/socket.py",
> > line 143, in _dummy
> >     raise error(EBADF, 'Bad file descriptor')
> > error: (9, 'Bad file descriptor')
> > --------------------------
> >
> > Of course the client then freezes:
> >
> >
> > ---- Client output ----
> > 124
> > Query sent...
> > (and freezes)
> >
> >
> > Does anyone have an explanation why this didn't work? Thanks a lot!
>
>
>




More information about the Python-list mailing list