使用socket和gevent在Python中发送和读取多个请求/响应

时间:2017-02-15 16:16:49

标签: python sockets asynchronous gevent spawn

我有同步实现在Python中发送多个请求并使用套接字接收多个响应:

# ATTENTION, SYNCHRONOUS WAY

import socket
from select import select
import ssl

host = '127.0.0.1'
port = 443
headers_with_body = 'HEADERS_AND_BODY_HERE'

s_ = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock = ssl.wrap_socket(s_, ca_certs='/usr/local/lib/python2.7/dist-packages/requests/cacert.pem', cert_reqs=ssl.CERT_NONE, ssl_version=ssl.PROTOCOL_TLSv1)

sock.connect((host, port))

for i in range(10):

    readable, writable, exceptional = select([sock], [sock], [], 0)

    if readable:
        data = sock.recv(4096)
        print 'Received request'
        print data

    if writable:
        print 'Sending request'
        sock.sendall(headers_with_body)

这段代码工作得很好,但它是异步的。因此,当我尝试向忙碌的服务器发送许多请求时,它会阻止,并且我无法在1秒内发送超过10个请求。

我发现我们可以使用gevent异步打开它,所以我改变了一点我的客户端代码:

# ASYNCHRONOUS WAY

import socket
from select import select
import ssl

import gevent
from gevent import monkey
monkey.patch_all()

host = '127.0.0.1'
port = 443
headers_with_body = 'HEADERS_AND_BODY_HERE'

s_ = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock = ssl.wrap_socket(s_, ca_certs='/usr/local/lib/python2.7/dist-packages/requests/cacert.pem', cert_reqs=ssl.CERT_NONE, ssl_version=ssl.PROTOCOL_TLSv1)

sock.connect((host, port))

for i in range(10):

    readable, writable, exceptional = select([sock], [sock], [], 0)

    if readable:
        data = sock.recv(4096)
        print 'Received request'
        print data

    if writable:
        jobs = [gevent.spawn(sock.sendall(headers_with_body)) for i in xrange(100)]
        gevent.joinall(jobs)     

此代码似乎运行良好(执行假定的工作 - 并行发送1000请求,但我无法读取每个请求的响应)。

有人可以帮我搞清楚吗?我可以说我是Python的新手,所以请帮我找到最简单的方法,在1或2秒内至少发送1000个并行请求(并收到1000个回复)。

只需考虑目标服务器在发送时可能正忙,因此响应可能会延迟到达。

任何帮助都会非常感激!

0 个答案:

没有答案