Python 尝试打开文件时一直出现 IO 错误
Python IO error all the time attempting to open a file
从命令行
client.py Aaron 12000 HelloWorld.html GET
client.py
def main(argv):
serverName = argv[0]
serverPort = int(argv[1])
fileName = argv[2]
typeOfHttpRequest = argv[3]
clientSocket = socket(AF_INET, SOCK_STREAM)
clientSocket.connect((serverName, serverPort))
clientSocket.send(typeOfHttpRequest + " " + fileName + " HTTP/1.1\r\n\r\n")
content = clientSocket.recv(1024)
print content
clientSocket.close()
if __name__ == "__main__":
main(sys.argv[1:])
server.py
while True:
#Establish the connection
print 'Ready to serve....'
connectionSocket, addr = serverSocket.accept()
try:
message = connectionSocket.recv(1024)
typeOfRequest = message.split()[0]
filename = message.split()[1]
print typeOfRequest
print filename
f = open(filename[1:])
outputdata = f.read()
if typeOfRequest == 'GET':
for i in range(0, len(outputdata)):
connectionSocket.send(outputdata[i])
connectionSocket.close()
elif typeOfRequest == 'HEAD':
connectionSocket.send(True)
except IOError:
connectionSocket.send('HTTP/1.1 404 Not Found')
connectionSocket.close()
serverSocket.close()
我已将 HelloWorld.html 放在与 server.py 相同的目录中,但这总是会产生 IOError。有人知道为什么会这样吗?
文件位于 C:\Networking
os.getcwd
显示 C:\Networking
HelloWorld.html 位于 C:/networking/HelloWorld.html
文件名打印正确。
您可能已经注意到,您试图从 URL 的开头删除 /
,尽管它并不存在。但是,您的代码中还有其他错误,这意味着它不像 HTTP 服务器那样工作:
首先,recv()
不能保证读取所有数据 - 即使总共有 1024 个字节写入套接字,recv(1024)
也可以 return 只读 10字节,比如说。因此最好循环执行:
buffer = []
while True:
data = connection_socket.recv(1024)
if not data:
break
buffer.append(data)
message = ''.join(buffer)
现在消息保证包含所有内容。
接下来,要处理请求的 header 行,您可以使用
from cStringIO import StringIO
message_reader = StringIO(message)
first_line = next(message_reader)
type_of_request, filename = message.split()[:2]
这样可以更轻松地扩展您的代码以获得更完整的 HTTP 支持。
现在用open
打开文件,用with
语句:
with open(filename) as f:
output_data = f.read()
这确保文件也正确关闭。
最后,当你回应请求时,你应该用HTTP/1.0
而不是HTTP/1.1
来回答,因为你不支持HTTP/1.1的全部范围。此外,即使 OK
响应也需要用完整的 header 响应,例如:
HTTP/1.1 200 OK
Server: My Python Server
Content-Length: 123
Content-Type: text/html;charset=UTF-8
data goes here....
因此您的发送例程应该这样做:
if typeOfRequest == 'GET':
headers = ('HTTP/1.0 200 OK\r\n'
'Server: My Python Server\r\n'
'Content-Length: %d\r\n'
'Content-Type: text/html;charset=UTF-8\r\n\r\n'
'Connection: close\r\n'
) % len(output_data)
connection_socket.sendall(headers)
connection_socket.sendall(output_data)
注意如何使用 sendall
发送字符串中的所有数据。
从命令行
client.py Aaron 12000 HelloWorld.html GET
client.py
def main(argv):
serverName = argv[0]
serverPort = int(argv[1])
fileName = argv[2]
typeOfHttpRequest = argv[3]
clientSocket = socket(AF_INET, SOCK_STREAM)
clientSocket.connect((serverName, serverPort))
clientSocket.send(typeOfHttpRequest + " " + fileName + " HTTP/1.1\r\n\r\n")
content = clientSocket.recv(1024)
print content
clientSocket.close()
if __name__ == "__main__":
main(sys.argv[1:])
server.py
while True:
#Establish the connection
print 'Ready to serve....'
connectionSocket, addr = serverSocket.accept()
try:
message = connectionSocket.recv(1024)
typeOfRequest = message.split()[0]
filename = message.split()[1]
print typeOfRequest
print filename
f = open(filename[1:])
outputdata = f.read()
if typeOfRequest == 'GET':
for i in range(0, len(outputdata)):
connectionSocket.send(outputdata[i])
connectionSocket.close()
elif typeOfRequest == 'HEAD':
connectionSocket.send(True)
except IOError:
connectionSocket.send('HTTP/1.1 404 Not Found')
connectionSocket.close()
serverSocket.close()
我已将 HelloWorld.html 放在与 server.py 相同的目录中,但这总是会产生 IOError。有人知道为什么会这样吗?
文件位于 C:\Networking
os.getcwd
显示 C:\NetworkingHelloWorld.html 位于 C:/networking/HelloWorld.html
文件名打印正确。
您可能已经注意到,您试图从 URL 的开头删除 /
,尽管它并不存在。但是,您的代码中还有其他错误,这意味着它不像 HTTP 服务器那样工作:
首先,recv()
不能保证读取所有数据 - 即使总共有 1024 个字节写入套接字,recv(1024)
也可以 return 只读 10字节,比如说。因此最好循环执行:
buffer = []
while True:
data = connection_socket.recv(1024)
if not data:
break
buffer.append(data)
message = ''.join(buffer)
现在消息保证包含所有内容。
接下来,要处理请求的 header 行,您可以使用
from cStringIO import StringIO
message_reader = StringIO(message)
first_line = next(message_reader)
type_of_request, filename = message.split()[:2]
这样可以更轻松地扩展您的代码以获得更完整的 HTTP 支持。
现在用open
打开文件,用with
语句:
with open(filename) as f:
output_data = f.read()
这确保文件也正确关闭。
最后,当你回应请求时,你应该用HTTP/1.0
而不是HTTP/1.1
来回答,因为你不支持HTTP/1.1的全部范围。此外,即使 OK
响应也需要用完整的 header 响应,例如:
HTTP/1.1 200 OK
Server: My Python Server
Content-Length: 123
Content-Type: text/html;charset=UTF-8
data goes here....
因此您的发送例程应该这样做:
if typeOfRequest == 'GET':
headers = ('HTTP/1.0 200 OK\r\n'
'Server: My Python Server\r\n'
'Content-Length: %d\r\n'
'Content-Type: text/html;charset=UTF-8\r\n\r\n'
'Connection: close\r\n'
) % len(output_data)
connection_socket.sendall(headers)
connection_socket.sendall(output_data)
注意如何使用 sendall
发送字符串中的所有数据。