为什么这个程序挂起?

时间:2012-08-22 19:32:01

标签: python sockets

我正在粘贴整个代码,因为我认为它只能得到它的简短;

import socket

def recv_all(sock):
    parts = []
    while True:
        msg = ""
        msg = sock.recv(4096)
        print "recieved", len(msg), "bytes."
        if not msg:
            break
        parts.append(msg)
    return "".join(parts)

http_request = """GET / HTTP/1.1
Host: {}
User-Agent: Opera/9.80 (Windows NT 6.1; WOW64; U; tr) Presto/2.10.229 Version/11.64
Accept: text/html, application/xml;q=0.9, application/xhtml xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1
Accept-Language: en
Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1
Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0
Connection: Keep-Alive, TE
TE: deflate, gzip, chunked, identity, trailers


"""
site = "www.google.com.tr"
print "creating connection"
conn = socket.create_connection((site,80))
print "sending data"
conn.sendall(http_request.format(site))
print "recieving response"
response = recv_all(conn)
print "closing connection"
conn.close()

print response

当我运行它时,我得到了这个输出;

creating connection
sending data
recieving response
recieved 3743 bytes.
recieved 4096 bytes.
recieved 4096 bytes.
recieved 4096 bytes.
recieved 3472 bytes.
recieved 1648 bytes.

我期望它做的是在读取最后一个块之后读取0个字节(在这种情况下为1648)。但它一直在等待。

我在使用Python 2.7的Windows 7上。

我在这里做错了什么?我该怎么办才能按预期工作?

3 个答案:

答案 0 :(得分:5)

您正在发送:

Connection: Keep-Alive, TE

...并且服务器完全按照您的要求进行操作 - 最后保持连接活动。因此,当服务器在同一连接上等待另一个请求时,您的读取调用会阻塞,等待更多数据。

关闭keep-alive查找Content-Length标头,并在阅读了那么多数据时停止阅读。

(或者,使用HTTP客户端库而不是自己尝试:)

答案 1 :(得分:1)

密钥位于您发送的HTTP请求中。见这一行:

  

连接:Keep-Alive,TE

这告诉另一方的服务器保持连接活动。

尝试:

  

连接:关闭

看看会发生什么。

答案 2 :(得分:0)

编辑:我误解了你的问题。虽然这不会导致您的挂起行为,但我认为您打算将最后msg添加到parts,这在最后一次运行时不会发生,因为您的if ... break语句位于.append之前1}}。