我正在编写一个非常基本的HTTP客户端:
import socket
from socket import *
Payload = """GET /test.html HTTP/1.1
Accept: */*
Accept-Language: en-us
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)
Accept-Encoding: gzip, deflate
Proxy-Connection: Keep-Alive
Host: example.com
Pragma: no-cache
"""
def SendAndReceive(Host, Payload):
s = socket(AF_INET, SOCK_STREAM)
s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
s.connect(Host)
s.sendall(Payload)
tdata=[]
while True:
data = s.recv(1024)
if not data:
break
tdata.append(data)
print ''.join(tdata)
return ''.join(tdata)
SendAndReceive(("www.example.com",80),Payload)
由于某些原因,recv()暂停一段时间(~10秒),然后返回数据。 我不确定我的代码有什么问题,非常感谢任何帮助。
谢谢!
答案 0 :(得分:2)
您执行的HTTP / 1.1请求隐含意味着保持活动,例如在请求完成后,服务器可以保持连接打开,以在同一连接上获得更多请求。在这种情况下,服务器在10秒后决定它不会等待更多请求,其他服务器可能会等待更长时间。您也不检查服务器对内容长度或分块编码的响应,但只是假设服务器将在请求完成后关闭。这是错误的(保持活着)。 此外,您有一个什么也不做的代理连接头,因为这不是代理请求(代理连接头本身无效,与代理通信需要连接头)。
最简单的方法是发出HTTP / 1.0请求,而不指定任何连接标头或将其设置为“关闭”。然后服务器将在响应完成后关闭连接。此外,您不必在这种情况下处理分块编码。
答案 1 :(得分:0)
正如Steffen所解释的那样,这是由于保持活力。例如,如果您使用google.com进行测试,则需要等待很长时间。您可以修改代码并按如下方式查看超时:
# Payload remains the same
import socket as socket_module
from socket import *
def SendAndReceive(Host, Payload):
s = socket(AF_INET, SOCK_STREAM)
s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
# or you could do s.setblocking(0) for timeout of 0 seconds
s.settimeout(1)
s.connect(Host)
s.sendall(Payload)
tdata=[]
while True:
try:
data = s.recv(1024)
except socket_module.error:
# TIMEOUT
break
if not data:
break
tdata.append(data)
print ''.join(tdata)
return ''.join(tdata)
这样你就不会收到错误。