我试图运行下面的python文件,服务器和客户端 它应该创建一个带有文件数据的http请求,当在客户端“127.0.0.1:8000”中输入为url时,它会获取数据并运行它 当我试图运行它即时获取错误的文件描述符 香港专业教育学院之前尝试过运行它,它现在有效但是现在......
"""
Developer: Roei Edri
File Name: httpServer.py
Exercise: 4.4
Date: 5.3.2018
"""
import socket
import os.path
IP = '127.0.0.1'
PORT = 8000
ROOT_PATH = "C:" + os.path.sep + "webroot"
class httpServer(object):
"""
Http server that supports html, js and css.
"""
# Status Codes
not_found = 'HTTP/1.1. 404 Not Found'
forbidden = 'HTTP/1.1 200 OK\r\n'
moved_temporarily = "HTTP/1.1 302 Moved Temporarily"
internal_server_error = "HTTP/1.1 500 Internal Server Error"
def __init__(self, ip, port, root):
self.ip = ip
self.port = port
self.root = root
def initiate_connection(self):
"""
Builds the connection between the client and server
Runs through a loop which means it can try to connect again and
again
after failure
"""
print("Initiating Connection...")
# Opens a socket and connects to the client
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((self.ip, self.port))
server_socket.listen(1)
client_socket, address = server_socket.accept()
# Entering a loop in order to be able to keep getting requests
while True:
print("Destination Address: " + str(address))
request = self.get_request(client_socket)
print(str(request))
# Checks weither whether the request contains a string (url)
if request:
request = ROOT_PATH + os.path.sep + \
request.replace("/", os.path.sep)
response = self.send_response(request)
print("trying to send response to client")
try:
client_socket.send(response)
except:
print("An error has occurred while sending the response
to\
the client")
# In case the request is invalid or empty
else:
if request == 0:
try:
client_socket.send(self.internal_server_error.encode())
except:
print("An error has occurred while sending the response\
to the client")
break
else:
break
try:
client_socket, address = server_socket.accept()
except:
print("An error has occurred when trying to initiate
connection\
")
break
# Closing connection
server_socket.close()
client_socket.close()
print("Closing connection...")
def get_request(self, client_socket):
"""
Gets the request from the client
In case of a non GET HTTP request, connection will be ended
:return: string/int: url/0
"""
try:
client_request = client_socket.recv(1024).decode()
client_request_list = client_request.split(" ")
print(client_request_list)
# Checking weither the request is a valid GET HTTP request
if (client_request_list[0] == "GET"):
return client_request_list[1]
if(client_request_list[2][:8] == "HTTP/1.1"):
return client_request_list[1]
except IndexError:
print "Index error occured when trying to get the http request"
return 0
def send_response(self, file_path):
"""
Gets the info from the request (the url) and returns a response
:param file_path: string
:return: tuple: (the file, the file extension)
"""
if file_path == '/' or file_path == \
(self.root + os.path.sep + os.path.sep):
file_path = self.root + os.path.sep + "index.html"
file_extension = file_path.split('.')[1]
# Checking weither the file exist or not
if os.path.isfile(file_path):
file_data = self.get_file(file_path)
response = 'HTTP/1.1 200 OK\r\n'
# Adding the headers
response += "Content-Length: " + str(len(file_data)) + "\r\n"
response += "Content-Type: " + \
self.set_content_type(file_extension) + "\r\n\r\n"
# Checking weither reponse is empty
if response:
response = "\r\n" + response.encode() + file_data
return response
else: # In case the response has am unknown extension, it's 500
return self.internal_server_error.encode()
return self.not_found.encode()
def set_content_type(self, file_ext):
if file_ext == "html" or file_ext == "txt":
return "text/html; charset=utf-8"
elif file_ext == "jpg":
return "image/jpeg"
elif file_ext == "js":
return "text/javascript; charset=UTF-8"
elif file_ext == "css":
return "text/css"
return ""
def get_file(self, file_path):
"""
Gets a path to a file and returnes the contained data
:param file_path: string
:return: string: file_data
"""
file = open(file_path, "rb")
file_data = file.read()
file.close()
return file_data
def main():
server = httpServer(IP, PORT, ROOT_PATH)
while True:
server.initiate_connection()
if __name__ == "__main__":
main()
完整错误
Traceback (most recent call last):
File "httpServer.py", line 165, in <module>
main()
File "httpServer.py", line 162, in main
server.initiate_connection()
File "httpServer.py", line 48, in initiate_connection
request = self.get_request(client_socket)
File "httpServer.py", line 93, in get_request
client_request = client_socket.recv(1024).decode()
File "C:\Python27\lib\socket.py", line 174, in _dummy
raise error(EBADF, 'Bad file descriptor')
socket.error: [Errno 9] Bad file descriptor
答案 0 :(得分:0)
def initiate_connection(self):
"""
Builds the connection between the client and server
Runs through a loop which means it can try to connect again and again
after failure
"""
print("Initiating Connection...")
# Opens a socket and connects to the client
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((self.ip, self.port))
server_socket.listen(1)
client_socket, address = server_socket.accept()
# Entering a loop in order to be able to keep getting requests
while True:
print("Destination Address: " + str(address))
request = self.get_request(client_socket)
print(str(request))
# Checks weither whether the request contains a string (url)
if request:
request = ROOT_PATH + os.path.sep + \
request.replace("/", os.path.sep)
response = self.send_response(request)
print("trying to send response to client")
try:
client_socket.send(response)
except:
print("An error has occurred while sending the response to\ the client")
# In case the request is invalid or empty
else:
if request == 0:
try:
client_socket.send(self.internal_server_error.encode())
except:
print("An error has occurred while sending the response\to the client")
break
else:
break
# Closing connection
client_socket.close()
print("Closing connection...")
try:
client_socket, address = server_socket.accept()
except:
print("An error has occurred when trying to initiate connection")
break
尝试使用initiate_connection函数。您在接受客户端连接后立即关闭它,然后尝试从中读取它。