python3 HTTPConnection抛出FileNotFoundError

时间:2013-10-16 22:59:02

标签: python http python-3.x

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

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

1 个答案:

答案 0 :(得分: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正在被翻译成一个友好的 - 但不是非常准确 - FileNotFoundError更远的链条,但这在这里并不太重要。)


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