【问题标题】:Python IO error all the time attempting to open a filePython IO错误一直试图打开一个文件
【发布时间】:2015-04-08 23:08:13
【问题描述】:

从命令行

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

  • 文件名打印正确。

【问题讨论】:

  • 文件名打印正确吗? IE。给open 的文件路径是否正确
  • 以后,对于错误消息,请始终包含完整的回溯。
  • 你能告诉我们os.getcwd() 是为你的服务器准备的吗?
  • 你是如何运行服务器的?是cd directory-for-server && python server.py 还是你叫它python /directory-for-server/server.py?
  • 为什么是filename[1:]?

标签: python sockets python-2.7 ioerror


【解决方案1】:

您可能已经注意到,您试图从 URL 的开头删除 /,尽管它不存在。但是,您的代码中还有其他错误,这意味着它不像 HTTP 服务器那样工作:

首先,recv() 不能保证读取所有数据 - 即使总共有 1024 个字节写入套接字,recv(1024) 也只能返回 10 个字节。因此最好循环执行:

buffer = []
while True:
    data = connection_socket.recv(1024)
    if not data:
        break
    buffer.append(data)

message = ''.join(buffer)

现在消息保证包含所有内容。

接下来,要处理请求的标题行,您可以使用

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 响应也需要使用完整的标头进行响应,例如:

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 发送字符串中的所有数据。

【讨论】:

    猜你喜欢
    • 2013-05-03
    • 2020-12-04
    • 2017-09-30
    • 2014-04-02
    • 2010-09-20
    • 1970-01-01
    • 2022-12-17
    • 2015-11-07
    • 2015-08-22
    相关资源
    最近更新 更多