2015-02-09 49 views
-5

从命令行Python的IO错误所有的时间试图打开一个文件

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() 

我已经把你好World.html与server.py位于同一目录中,但这总是会产生IOError。任何人都知道为什么它可能是这种情况?

  • 该文件位于C:\网络

  • os.getcwd示出了C:\网络

  • HelloWorld.html的位于C:/networking/HelloWorld.html

  • 文件名打印正确。

enter image description here

+0

并且文件名打印出来是否正确?即是给“open”正确的文件路径 – 2015-02-09 08:57:17

+1

将来,对于错误消息,请始终包含* full tr​​aceback *。 – 2015-02-09 08:58:45

+0

你能告诉我们什么'os.getcwd()'是你的服务器? – 2015-02-09 09:00:11

回答

11

正如你可能已经注意到,您试图剥去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从发送的所有数据串。

相关问题