2013-10-16 34 views
0

我正在尝试使用python3 http.client创建HTTPConnection。这里是我的代码:python3 HTTPConnection引发FileNotFoundError

import http.client 
import base64 
if __name__ == '__main__': 
    username = "xx" # enter your username 
    password = "xxx" # enter your password 
    device_id = "00000000-00000000-00409DFF-FF7660EC" # enter device id of target 
    # Nothing below this line should need to be changed 
    # ------------------------------------------------- 

    # create HTTP basic authentication string, this consists of 
    encodestring = '%s:%s' % (username, password) 
    auth = base64.encodebytes(encodestring.encode('utf-8'))[:-1] 
    # message to send to server 
    message = """<sci_request version="1.0"> 
    <send_message> 
     <targets> 
     <device id="%s"/> 
     </targets> 
     <rci_request version="1.1"> 
      <query_state/> 
     </rci_request> 
    </send_message> 
    </sci_request> 
    """%(device_id) 
    webservice = http.client.HTTPConnection("login.etherios.com ", 80) 
    # to what URL to send the request with a given HTTP method 
    webservice.putrequest("POST", "/ws/sci")  
    # add the authorization string into the HTTP header 
    webservice.putheader("Authorization", "Basic %s" % auth) 
    webservice.putheader("Content-type", "text/xml; charset=\"UTF-8\"") 
    webservice.putheader("Content-length", "%d" % len(message)) 
    webservice.endheaders() 
    webservice.send(message) 
    # get the response 
    statuscode, statusmessage, header = webservice.getreply() 
    response_body = webservice.getfile().read() 
    # print the output to standard out 
    print (statuscode, statusmessage) 
    print (response_body) 

错误消息当我运行该脚本

FileNotFoundError: [Errno 2] No such file or directory 

错误点到线40(webservice.endheaders()),我觉得这有点混乱。任何人都可以阐明错误信息吗?

以下是完整的回溯:

In [47]: run import_sensor 
--------------------------------------------------------------------------- 
FileNotFoundError       Traceback (most recent call last) 
/usr/lib/python3/dist-packages/IPython/utils/py3compat.py in execfile(fname, glob, loc) 
    74  def execfile(fname, glob, loc=None): 
    75   loc = loc if (loc is not None) else glob 
---> 76   exec(compile(open(fname, 'rb').read(), fname, 'exec'), glob, loc) 
    77 
    78  # Refactor print statements in doctests. 

/home/markus/python/precirrr-py/precirr/import_sensor.py in <module>() 
    38  webservice.putheader("Content-type", "text/xml; charset=\"UTF-8\"") 
    39  webservice.putheader("Content-length", "%d" % len(message)) 
---> 40  webservice.endheaders() 
    41  webservice.send(message) 
    42  # get the response 

/usr/lib/python3.3/http/client.py in endheaders(self, message_body) 
    1055   else: 
    1056    raise CannotSendHeader() 
-> 1057   self._send_output(message_body) 
    1058 
    1059  def request(self, method, url, body=None, headers={}): 

/usr/lib/python3.3/http/client.py in _send_output(self, message_body) 
    900    msg += message_body 
    901    message_body = None 
--> 902   self.send(msg) 
    903   if message_body is not None: 
    904    # message_body was not a string (i.e. it is a file), and 

/usr/lib/python3.3/http/client.py in send(self, data) 
    838   if self.sock is None: 
    839    if self.auto_open: 
--> 840     self.connect() 
    841    else: 
    842     raise NotConnected() 

/usr/lib/python3.3/http/client.py in connect(self) 
    816   """Connect to the host and port specified in __init__.""" 
    817   self.sock = socket.create_connection((self.host,self.port), 
--> 818            self.timeout, self.source_address) 
    819   if self._tunnel_host: 
    820    self._tunnel() 

/usr/lib/python3.3/socket.py in create_connection(address, timeout, source_address) 
    415  host, port = address 
    416  err = None 
--> 417  for res in getaddrinfo(host, port, 0, SOCK_STREAM): 
    418   af, socktype, proto, canonname, sa = res 
    419   sock = None 

FileNotFoundError: [Errno 2] No such file or directory 
+0

你确实在'HTTPConnection'构造函数的主机名末尾有多余的空间吗?因为在你进入“endheaders”之前,这应该给你一个'gaierror'或类似的东西。 – abarnert

+0

与此同时,你会在'send'上得到一个'TypeError';你不能在套接字上发送'str';你必须把它编码成字节。而'getreply'会引发'AttributeError',因为没有这样的方法。 (也许你的意思是'getresponse'?) – abarnert

+0

和'getfile'一样。没有这样的方法;你从'getresponse'返回的'HTTPResponse'对象上调用'read'。你从哪里得到这个代码?如果它是从教程复制的,您可能想要找到更好的教程... – abarnert

回答

1

的问题是在这里:

webservice = http.client.HTTPConnection("login.etherios.com ", 80) 

这在"login.etherios.com "年底额外的空间意味着它不是一个有效的DNS名称。例如:

>>> socket.getaddrinfo('login.etherios.com', 80, 0, socket.SOCK_STREAM) 
[(2, 1, 6, '', ('108.166.22.160', 80))] 
>>> socket.getaddrinfo('login.etherios.com ', 80, 0, socket.SOCK_STREAM) 
gaierror: [Errno 8] nodename nor servname provided, or not known 

(不友好gaierror被翻译成一个友好的,但不是很accurate- FileNotFoundError更远环比上涨,但在这里,这不是太重要)


那么,为什么你是否看到错误在webservice.endheaders()一路下降?那么,Python正在努力在这里变得聪明。如果它立即打开套接字,然后按照您提供的方式一次发送一行数据,而让套接字坐在中间,则可能会浪费您计算机上的CPU和网络资源,可能是远程服务器和/或路由器,甚至可能在互联网上。打开连接并立即发送整个请求(或者当您有大量数据时,至少直到标题的结尾),会更好。所以,Python试图为你做到这一点。这意味着在实际尝试使用它之前,它不会意识到你给了它不好的信息。

+0

非常感谢您的帮助。一个微小的空间和这样的影响。解决这个问题之后,我能够正确设置编码,相应地调整方法名称,并最终奏效。 –