我正在尝试使用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
答案 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试图为你做到这一点。这意味着在实际尝试使用它之前,它不会意识到你已经给出了错误的信息。