Python Recv()暂停

2024-10-03 00:32:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在编写一个非常基本的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秒),然后返回数据。 我不知道我的代码出了什么问题,任何帮助都将不胜感激。在

谢谢!在


Tags: fromimportcomhttphost客户端dataexample
2条回答

正如Steffen所解释的,这是由于keep-alive。例如,如果使用谷歌,你会等很长时间。您可以修改代码并查看超时情况,如下所示:

# 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)

这样你就不会出错了。在

您执行一个HTTP/1.1请求,它隐含地意味着保持活动,例如,服务器可以在请求完成后保持连接打开,以便在同一连接上获得更多请求。在这种情况下,服务器在10秒后决定不再等待更多请求,其他服务器可能会等待更长时间。您也不检查服务器响应的内容长度或分块编码,而只是假设,一旦请求完成,服务器将关闭。这是错误的。 另外,您有一个代理连接头,它什么也不做,因为这不是一个代理请求(代理连接头本身是无效的,与代理通信需要连接头)。在

最简单的方法是发出HTTP/1.0请求,而不指定任何连接头或将其设置为“close”。然后服务器将在响应完成后关闭连接。而且,在这种情况下,您不必处理分块编码。在

相关问题 更多 >