Reputation: 4240
I'm trying to write a really simple web server with Python that is multithreaded. Right now the code looks like this
from socket import *
import threading
import time
class serverThread(threading.Thread):
def __init__(self, serverPort):
threading.Thread.__init__(self)
self.serverPort = serverPort
self.serverSocket = socket(AF_INET, SOCK_STREAM)
self.connectionThreads = []
def run(self):
self.serverSocket.bind(('', self.serverPort))
self.serverSocket.listen(1)
while True:
#Establish the connection
print 'Ready to serve...'
connectionSocket = self.serverSocket.accept()
message = connectionSocket.recv(1024) #Get message
print "Message recieved, opening new thread"
self.connectionThreads.append(connectionThread())
self.connectionThreads[len(connectionThreads)-1].start()
def close(self):
for t in self.connectionThreads:
t.close()
self.serverSocket.close()
class connectionThread (threading.Thread):
def __init__(self, connSocket, message):
threading.Thread.__init__(self)
self.connSocket = connSocket
self.message = message
def run(self):
try:
filename = self.message.split()[1] #Getting requested HTML page
f = open(filename[1:]) #Opening data stream from HTML
outputdata = f.read() #Reading HTML page
f.close() #Closing data stream from HTML
self.connSocket.send("HTTP/1.0 200 OK\r\n") #Send one HTTP header line into socket
for i in range(0, len(outputdata)): #Send the content of the requested file to the client
self.connSocket.send(outputdata[i])
except IOError: #Triggered if user requests bad link
self.connSocket.send("404 Not Found") #Send response message for file not found
finally:
self.connSocket.close()
def main():
server = serverThread(8031)
server.start()
end = raw_input("Press enter to stop server...")
server.close()
print "Program complete"
main()
My strategy is to start the web server in the main method and then start connection threads from the server thread. I have a simple helloworld html file in the same directory which I'm using to test it from localhost
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
HELLO WORLD!
</body>
</html>
However, when I go to type localhost:8031/hello.html in Chrome, it just loads forever saying "waiting for localhost". I have a print that is supposed to happen whenever a new message is received but it's not printing which tells me the server is not receiving messages properly
When I try to connect a second time Chrome flat out tells me the connection was refused and when I press enter to stop the server it seems to quit fine but then I get an error message
I'm frustrated and not sure how to debug this so any help would be greatly appreciated!
Upvotes: 0
Views: 3797
Reputation: 77337
You have several errors in your code that I went through in the posted code below. General notes are:
Fixing up the errors I came up with
from socket import *
import threading
import time
class serverThread(threading.Thread):
def __init__(self, serverPort):
threading.Thread.__init__(self)
self.serverPort = serverPort
self.serverSocket = socket(AF_INET, SOCK_STREAM)
self.serverSocket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
self.connectionThreads = []
def run(self):
self.serverSocket.bind(('', self.serverPort))
self.serverSocket.listen(1)
while True:
#Establish the connection
print 'Ready to serve...'
connectionSocket,addr = self.serverSocket.accept()
message = connectionSocket.recv(1024) #Get message
print "Message recieved, opening new thread"
self.connectionThreads.append(connectionThread(connectionSocket, message))
self.connectionThreads[-1].daemon = 1
self.connectionThreads[-1].start()
def close(self):
for t in self.connectionThreads:
try:
t.connSocket.shutdown(SHUT_RDWR)
t.connSocket.close()
except socket.error:
pass
self.serverSocket.shutdown(SHUT_RDWR)
self.serverSocket.close()
class connectionThread (threading.Thread):
def __init__(self, connSocket, message):
threading.Thread.__init__(self)
self.connSocket = connSocket
self.message = message
def run(self):
try:
filename = self.message.split()[1] #Getting requested HTML page
f = open(filename[1:]) #Opening data stream from HTML
outputdata = f.read() #Reading HTML page
f.close() #Closing data stream from HTML
self.connSocket.send("HTTP/1.0 200 OK\r\n") #Send one HTTP header line into socket
for i in range(0, len(outputdata)): #Send the content of the requested file to the client
self.connSocket.send(outputdata[i])
except IOError: #Triggered if user requests bad link
self.connSocket.send("404 Not Found") #Send response message for file not found
finally:
self.connSocket.shutdown(SHUT_RDWR)
self.connSocket.close()
def main():
server = serverThread(8031)
server.daemon = 1
server.start()
end = raw_input("Press enter to stop server...")
server.close()
print "Program complete"
main()
Upvotes: 0
Reputation: 154
Apparently you are trying to access a file or socket you already closed.
See line:
sock, addr = self._sock.accept()
You are trying to accept a request with a socket that you already closed.
Check the file descriptor(could be a socket) that is usually represented as a number.
Upvotes: 1