【问题标题】:How to emulate socket.socketpair on Windows如何在 Windows 上模拟 socket.socketpair
【发布时间】:2014-07-24 12:14:48
【问题描述】:

遗憾的是,标准 Python 函数 socket.socketpair 在 Windows 上不可用(从 Python 3.4.1 开始),我如何编写一个在 Unix 和 Windows 上都可以使用的替代函数?

【问题讨论】:

    标签: python windows sockets python-3.4


    【解决方案1】:

    Python 3.5 包括 Windows 对 socket.socketpair() 的支持。对于 Python 2.7+,您可以在 PyPi 上使用 backports.socketpair package(我编写的):

    import socket
    import backports.socketpair
    
    s1, s2 = socket.socketpair()
    

    【讨论】:

    • 如果可以的话,我会不止一次 +1,因为从 Python 3.5 开始这个问题就消失了,并且有一个 PyPi 包可以在没有它的版本上填充它,回答了无疑使几乎每个人都想到这个问题的实际根本问题。
    • 请添加完整代码,因为链接(即使是 PyPi 或 GitHub 的链接)可能会中断。无论如何 +1。
    【解决方案2】:
    import socket
    import errno
    
    
    def create_sock_pair(port=0):
        """Create socket pair.
    
        If socket.socketpair isn't available, we emulate it.
        """
        # See if socketpair() is available.
        have_socketpair = hasattr(socket, 'socketpair')
        if have_socketpair:
            client_sock, srv_sock = socket.socketpair()
            return client_sock, srv_sock
    
        # Create a non-blocking temporary server socket
        temp_srv_sock = socket.socket()
        temp_srv_sock.setblocking(False)
        temp_srv_sock.bind(('', port))
        port = temp_srv_sock.getsockname()[1]
        temp_srv_sock.listen(1)
    
        # Create non-blocking client socket
        client_sock = socket.socket()
        client_sock.setblocking(False)
        try:
            client_sock.connect(('localhost', port))
        except socket.error as err:
            # EWOULDBLOCK is not an error, as the socket is non-blocking
            if err.errno != errno.EWOULDBLOCK:
                raise
    
        # Use select to wait for connect() to succeed.
        import select
        timeout = 1
        readable = select.select([temp_srv_sock], [], [], timeout)[0]
        if temp_srv_sock not in readable:
            raise Exception('Client socket not connected in {} second(s)'.format(timeout))
        srv_sock, _ = temp_srv_sock.accept()
    
        return client_sock, srv_sock
    

    【讨论】:

    • 我会使用 errno.EWOULDBLOCK 而不是数字 10035。
    猜你喜欢
    • 2010-11-09
    • 1970-01-01
    • 1970-01-01
    • 2010-10-25
    • 1970-01-01
    • 1970-01-01
    • 2011-10-29
    • 1970-01-01
    • 2012-06-10
    相关资源
    最近更新 更多