我一直在尝试运行此代码以开始与其他站点的通信,但是无法建立一个。有人可以帮我解决我在这里缺少的东西吗?
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print(s)
server = 'www.python.org'
port = 80 #defining port / acting like a browser
server_ip = socket.gethostbyname(server)
print(server_ip)
request = "GET / HTTPS/1.1\nHost: "+server+"\n\n"
s.connect((server_ip,port))
s.send(request.encode())
result = s.recv(4096)
while (len(result) > 0):
print(result)
result = s.recv(1024)
每次在不同的站点上,我都收到以下错误消息:
<socket.socket fd=508, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0>
151.101.152.223 b'HTTP / 1.1 301永久移动\ r \ n服务器:Varnish \ r \ n重试后:0 \ r \ n位置:https://www.python.org/ \ r \ n内容长度:0 \ r \ n接受范围:字节\ r \ n日期:2018年12月5日星期三17:10:03 GMT \ r \ nVia:1.1清漆\ r \ n连接:close \ r \ nX-Served-By:cache-bom18222-BOM \ r \ nX-Cache:HIT \ r \ nX-Cache-Hits:0 \ r \ nX-Timer:S1544029803.224270,VS0,VE0 \ r \ n严格传输安全性:max-age = 63072000; includeSubDomains \ r \ n \ r \ n'
答案 0 :(得分:0)
此请求在多个级别上都是错误的:
port = 80 #defining port / acting like a browser
...
request = "GET / HTTPS/1.1\nHost: "+server+"\n\n"
没有HTTPS/1.1
协议。只有HTTP/1.1
。要访问https://..
URL,您需要先连接到站点(默认端口443,而不是您使用的80),upgrade the TCP socket to SSL并发出正确的HTTP请求,即使用HTTP/1.1
HTTPS/1.1
。
另外,行和标题定界符必须为\r\n
,而不仅仅是您使用的\n
。不过,大多数服务器都会忽略差异。
此外,HTTP/1.1
隐式启用持久HTTP连接(HTTP保持活动状态)。这意味着服务器可能不会像您的代码预期的那样在响应后立即关闭连接,但是可能会等待很长时间才能在同一连接中等待更多请求。对于此类简单请求,最好使用HTTP/1.0
,它没有隐式的保持活动状态,并且在其他方面也更简单(没有分块传输编码)。
.... b'HTTP/1.1 301 Moved Permanently ... Location: https://www.python.org/
这甚至不是错误。这是一个HTTP重定向,它指示您应使用https://
访问该站点(您可能尝试这样做但使用了错误的方式)。
最后,您的代码可能如下所示:
import socket
import ssl
(server,port) = ('www.python.org',443)
request = "GET / HTTP/1.0\r\nHost: "+server+"\r\n\r\n"
s = socket.socket()
s.connect((server,port))
s = ssl.create_default_context().wrap_socket(s, server_hostname=server)
s.send(request.encode())
result = s.recv(4096)
while (len(result) > 0):
print(str(result))
result = s.recv(1024)
尽管如此,即使此代码正常工作,我也建议使用requests之类的HTTP库。如果您坚持要编写自己的HTTP堆栈,那么请研究该标准-该协议比仅仅看几个示例所建议的要复杂得多。