使用poll函数过滤掉可读文件描述符

时间:2015-11-02 06:03:36

标签: python select

我遇到代码错误:

File "/usr/local/lib/python2.7/site-packages/requests/packages/urllib3/contrib/pyopenssl.py", line 285, in ssl_wrap_socket
rd, _, _ = select.select([sock], [], [], sock.gettimeout())
ValueError: filedescriptor out of range in select()

这意味着具有select()功能的文件描述符太多。代码是here。 也许出于可移植性的原因,代码使用select()来过滤掉可读的描述符, 但我需要无限的文件描述符号,所以我必须用poll函数更改代码。 代码在Linux系统上运行;便携式思维将被忽略。 这是我的get rd代码。我是poll()函数的新手;我的实施有什么问题吗?

该功能如下所示:

def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None,
                    ca_certs=None, server_hostname=None,
                    ssl_version=None, ca_cert_dir=None):
    ctx = OpenSSL.SSL.Context(_openssl_versions[ssl_version])
    if certfile:
        keyfile = keyfile or certfile  # Match behaviour of the normal python ssl library
        ctx.use_certificate_file(certfile)
    if keyfile:
        ctx.use_privatekey_file(keyfile)
    if cert_reqs != ssl.CERT_NONE:
        ctx.set_verify(_openssl_verify[cert_reqs], _verify_callback)
    if ca_certs or ca_cert_dir:
        try:
            ctx.load_verify_locations(ca_certs, ca_cert_dir)
        except OpenSSL.SSL.Error as e:
            raise ssl.SSLError('bad ca_certs: %r' % ca_certs, e)
    else:
        ctx.set_default_verify_paths()

    # Disable TLS compression to migitate CRIME attack (issue #309)
    OP_NO_COMPRESSION = 0x20000
    ctx.set_options(OP_NO_COMPRESSION)

    # Set list of supported ciphersuites.
    ctx.set_cipher_list(DEFAULT_SSL_CIPHER_LIST)

    cnx = OpenSSL.SSL.Connection(ctx, sock)
    cnx.set_tlsext_host_name(server_hostname)
    cnx.set_connect_state()
    while True:
        try:
            cnx.do_handshake()
        except OpenSSL.SSL.WantReadError:

            READ_ONLY = ( select.POLLIN | select.POLLPRI | select.POLLHUP | select.POLLERR)
            poller = select.poll()
            poller.register(sock, READ_ONLY)
            fd_to_socket = {sock.fileno():sock,}
            events = poller.poll(sock.gettimeout())

            rd = []
            for fd, flag in events:
                s = fd_to_socket[fd]
                if flag & (select.POLLIN | select.POLLPRI):
                    is s is sock:
                        rd.append(s)

            if not rd:
                raise timeout('poll timed out')

            continue
        except OpenSSL.SSL.Error as e:
            raise ssl.SSLError('bad handshake: %r' % e)
        break

    return WrappedSocket(cnx, sock)

0 个答案:

没有答案