qmsk/net/transport/socket.py
author Tero Marttila <terom@fixme.fi>
Fri, 21 Aug 2009 00:30:06 +0300
changeset 28 020c89baaa33
child 33 c71de00715d6
permissions -rw-r--r--
[transport] initial TCP implementation
28
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     1
"""
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     2
    Socket implementation helpers
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     3
"""
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     4
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     5
from qmsk.net.socket import socket
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     6
from qmsk.net.socket.constants import *
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     7
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     8
class SocketError (Exception) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     9
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    10
        Base class of errors raised by the Socket classes.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    11
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    12
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    13
class SocketBindAddrinfoError (SocketError) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    14
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    15
        The socket was unable to socket()+bind() to the given addrinfo.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    16
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    17
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    18
    def __init__ (self, addrinfo, error) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    19
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    20
            addrinfo            - the addrinfo we tried to use
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    21
            error               - the resulting error
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    22
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    23
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    24
        self.addrinfo = addrinfo
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    25
        self.error = error
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    26
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    27
    def __str__ (self) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    28
        return "Unable to bind() to %s: %s" % (self.addrinfo, self.error)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    29
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    30
class SocketBindEndpointError (SocketError) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    31
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    32
        The socket was unable to bind() to the any of the given endpoint's addresses.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    33
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    34
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    35
    def __init__ (self, endpoint, errors) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    36
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    37
            endpoint            - the endpoint we tried to bind to
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    38
            errors              - a sequence of ServiceBindAddrinfoErrors describing the failed bind attempts.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    39
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    40
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    41
        self.endpoint = endpoint
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    42
        self.errors = errors
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    43
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    44
    def __str__ (self) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    45
        # XXX: too verbose?
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    46
        return "Unable to bind() to any addresses on endpoint %s:\n%s" % (self.endpoint, "\n".join(
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    47
            "\t%s" % (error, ) for error in self.errors
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    48
        ))
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    49
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    50
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    51
class Base (object) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    52
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    53
        Base class for all other socket-related classes, contains the underlying socket object.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    54
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    55
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    56
    # the underlying socket object
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    57
    sock = None
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    58
    
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    59
    def _init_sock (self, sock) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    60
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    61
            Initialize with the given pre-existing socket.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    62
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    63
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    64
        self.sock = sock
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    65
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    66
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    67
class Common (Base) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    68
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    69
        Common operations for Client/Service
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    70
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    71
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    72
    @classmethod
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    73
    def _socket (self, family, socktype, protocol = 0) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    74
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    75
            Construct and return a new socket object using the given parameters.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    76
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    77
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    78
        return socket.socket(family, socktype, protocol)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    79
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    80
    @classmethod
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    81
    def _bind_addrinfo (cls, ai) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    82
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    83
            This will attempt to create a new socket and bind it, based on the given addrinfo, returning the new socket.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    84
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    85
            Raises a ServiceBindAddrinfoError if this fails
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    86
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    87
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    88
        try :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    89
            # socket()
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    90
            sock = self._socket(ai.family, ai.socktype, ai.protocol)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    91
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    92
            # bind()
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    93
            sock.bind(ai.addr)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    94
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    95
        # XXX: except socket.error as e :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    96
        except OSError, error : 
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    97
            raise SocketBindAddrinfoError(ai, error)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    98
           
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    99
        else :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   100
            return sock
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   101
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   102
    @classmethod
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   103
    def _bind_endpoint (cls, endpoint, family, socktype, protocol=0) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   104
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   105
            This will resolve the given endpoint, and attempt to create and bind a suitable socket and return it.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   106
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   107
                endpoint        - local Endpoint to bind() to.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   108
                family          - socket address family to use.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   109
                socktype        - socket type to use
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   110
                protocol        - (optional) specific protocol
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   111
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   112
            Raises a ServiceBindError if this is unable to create a bound socket.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   113
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   114
            XXX: bind to all of the given endpoint's addresses instead of just one...?
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   115
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   116
        
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   117
        errors = []
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   118
        
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   119
        # resolve the endpoint and try socket+bind
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   120
        for ai in endpoint.getaddrinfo(family, socktype, protocol, AI_PASSIVE) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   121
            try :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   122
                # try to socket+bind this addrinfo
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   123
                sock = cls._bind_addrinfo(ai)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   124
            
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   125
            except SocketBindAddrinfoError, error :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   126
                # collect
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   127
                errors.append(error)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   128
                
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   129
                # keep trying
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   130
                continue
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   131
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   132
            else :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   133
                # got a working socket :)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   134
                return sock
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   135
       
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   136
        else :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   137
            # no suitable address found :(
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   138
            raise SocketBindEndpointError(endpoint, errors)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   139
    
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   140
    def _init_endpoint (self, endpoint, family, socktype, protocol = 0) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   141
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   142
            Initialize this socket by constructing a new socket with the given parameters, bound to the given endpoint,
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   143
            if given. If no endpoint is given, this simply creates a socket with the given settings and does not bind
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   144
            it anywhere.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   145
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   146
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   147
        # create local socket
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   148
        if endpoint :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   149
            # create a suitable socket bound to a the given endpoint
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   150
            self.sock = self._bind_endpoint(endpoint, family, socktype, protocol)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   151
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   152
        else :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   153
            # create a suitable socket not bound to anything
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   154
            self.sock = self._socket(family, socktype, protocol)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   155
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   156
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   157
class Service (Common) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   158
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   159
        Listener socket
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   160
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   161
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   162
    def _listen (self, backlog) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   163
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   164
            Puts this socket into listen() mode with the given backlog.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   165
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   166
        
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   167
        self.sock.listen(backlog)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   168
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   169
class SocketConnectAddrinfoError (SocketError) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   170
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   171
        The socket was unable to socket()+connect() to the given addrinfo.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   172
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   173
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   174
    def __init__ (self, addrinfo, error) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   175
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   176
            addrinfo            - the addrinfo we tried to use
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   177
            error               - the resulting error
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   178
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   179
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   180
        self.addrinfo = addrinfo
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   181
        self.error = error
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   182
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   183
    def __str__ (self) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   184
        return "Unable to connect() to %s: %s" % (self.addrinfo, self.error)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   185
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   186
class SocketConnectEndpointError (SocketError) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   187
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   188
        The socket was unable to connect() to the any of the given endpoint's addresses.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   189
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   190
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   191
    def __init__ (self, endpoint, errors) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   192
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   193
            endpoint            - the endpoint we tried to connect to
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   194
            errors              - a sequence of ServiceBindAddrinfoErrors describing the failed connect attempts.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   195
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   196
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   197
        self.endpoint = endpoint
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   198
        self.errors = errors
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   199
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   200
    def __str__ (self) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   201
        # XXX: too verbose?
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   202
        return "Unable to connect() to any addresses on endpoint %s:\n%s" % (self.endpoint, "\n".join(
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   203
            "\t%s" % (error, ) for error in self.errors
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   204
        ))
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   205
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   206
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   207
class Client (Common) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   208
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   209
        Connecting socket
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   210
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   211
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   212
    @classmethod
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   213
    def _connect_sock_addr (cls, sock, addr) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   214
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   215
            Attempt to connect the given socket to the given address.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   216
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   217
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   218
        sock.connect(addr)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   219
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   220
    @classmethod
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   221
    def _connect_sock_addrinfo (cls, sock, ai) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   222
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   223
            Attempt to connect the given socket to the given addrinfo's address.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   224
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   225
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   226
        try :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   227
            cls._connect_sock_addr(sock, ai.addr)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   228
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   229
        # XXX: except socket.error as e :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   230
        except OSError, error :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   231
            raise SocketConnectAddrinfoError(ai, error)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   232
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   233
    @classmethod
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   234
    def _connect_addrinfo (cls, ai) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   235
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   236
            Attempt to create a socket and connect it based on the given addrinfo, returning the new socket is succesfull.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   237
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   238
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   239
        try :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   240
            # socket()
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   241
            sock = cls._socket(ai.family, ai.socktype, ai.protocol)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   242
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   243
        # XXX: except socket.error as e :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   244
        except OSError, error : 
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   245
            raise SocketConnectAddrinfoError(ai, error)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   246
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   247
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   248
        # try and connect() it
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   249
        cls._connect_sock_addrinfo(sock, ai)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   250
        
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   251
        # return once succesfully
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   252
        return sock
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   253
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   254
    @classmethod
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   255
    def _connect_sock_endpoint (cls, sock, endpoint, family, socktype, protocol = 0) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   256
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   257
            Connect this socket to the given remote endpoint, using the given parameters to resolve the endpoint.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   258
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   259
        
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   260
        errors = []
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   261
        
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   262
        # resolve the endpoint and try socket+bind
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   263
        for ai in endpoint.getaddrinfo(family, socktype, protocol) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   264
            try :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   265
                # try to connect the socket to this addrinfo
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   266
                cls._connect_sock_addrinfo(sock, ai)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   267
            
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   268
            except SocketConnectAddrinfoError, error :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   269
                # collect
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   270
                errors.append(error)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   271
                
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   272
                # keep trying
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   273
                continue
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   274
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   275
            else :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   276
                # got a working socket :)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   277
                return
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   278
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   279
        else :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   280
            # no suitable address found :(
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   281
            raise SocketConnectEndpointError(endpoint, errors)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   282
    
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   283
    @classmethod
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   284
    def _connect_endpoint (self, endpoint, family, socktype, protocol = 0) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   285
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   286
            Create a new socket and connect it to the given remote endpoint, using the given parameters to resolve the
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   287
            endpoint.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   288
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   289
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   290
        errors = []
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   291
        
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   292
        # resolve the endpoint and try socket+bind
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   293
        for ai in endpoint.getaddrinfo(family, socktype, protocol) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   294
            try :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   295
                # try to socket+connect this addrinfo
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   296
                sock = cls._connect_addrinfo(ai)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   297
            
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   298
            except SocketConnectAddrinfoError, error :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   299
                # collect
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   300
                errors.append(error)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   301
                
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   302
                # keep trying
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   303
                continue
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   304
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   305
            else :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   306
                # got a working socket :)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   307
                return sock
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   308
       
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   309
        else :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   310
            # no suitable address found :(
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   311
            raise SocketConnectEndpointError(endpoint, errors)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   312
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   313
    def _init_connect_endpoint (self, endpoint, family, socktype, protocol = 0):
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   314
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   315
            If we already have an existing socket, connect it to the given endpoint, otherwise try and connect to the
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   316
            given endpoint with a new socket.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   317
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   318
            There is a subtle difference here, because if we have e.g. an IPv4 socket and try and connect it to an
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   319
            endpoint with both IPv6 and IPv4 addresses, we will try to connect to an IPv6 address using the IPv4 socket,
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   320
            and then to the IPv4 address using the IPv6 socket.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   321
            
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   322
            If we do not yet have a socket, then we will attempt to connect to the IPv6 address using an IPv6 socket,
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   323
            and to the IPv4 address using an IPv4 socket.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   324
        """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   325
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   326
        if self.socket :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   327
            # connect with existing socket
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   328
            self._connect_sock_endpoint(self.socket, endpoint, family, socktype, protocol)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   329
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   330
        else :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   331
            # connect with new socket
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   332
            self._connect_endpoint(endpoint, family, socktype, protocol)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   333
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   334
class Stream (Base) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   335
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   336
        Unbuffered byte-stream interface.
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   337
    """
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   338
   
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   339
    def read (self, iov) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   340
        return self.sock.read(iov)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   341
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   342
    def readv (self, iovecs) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   343
        return self.sock.readv(iovecs)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   344
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   345
    def write (self, buf) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   346
        return self.sock.write(buf)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   347
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   348
    def writev (self, iovecs) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   349
        return self.sock.writev(iovecs)
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   350
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   351
    def close (self) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   352
        self.sock.close()
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   353
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   354
    def abort (self) :
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   355
        # XXX: SO_LINGER magic
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   356
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   357
        raise NotImplementedError()
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   358
020c89baaa33 [transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   359