Threaded server: what's wrong with this code?
Fortepianissimo
fortepianissimo at yahoo.com.tw
Wed Dec 24 16:45:17 EST 2003
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