0

我正在尝试创建一个HTTPConnectionusing python3 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
4

1 回答 1

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的被翻译成友好的——但不是很准确——<code>FileNotFoundError 更远的链,但这在这里并不重要。)


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

于 2013-10-16T23:59:28.067 回答