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