31 |
31 |
32 class Service (socket.Service, service.Service) : |
32 class Service (socket.Service, service.Service) : |
33 """ |
33 """ |
34 An implementation of Service for TCP sockets. |
34 An implementation of Service for TCP sockets. |
35 """ |
35 """ |
|
36 |
|
37 _SOCKTYPE = socket.SOCK_STREAM |
36 |
38 |
37 def __init__ (self, endpoint, af=socket.AF_UNSPEC, listen_backlog=LISTEN_BACKLOG) : |
39 def __init__ (self, endpoint, listen_backlog=LISTEN_BACKLOG, family=None) : |
38 """ |
40 """ |
39 Construct a service, bound to the given local endpoint and listening for incoming connections using the |
41 Construct a service, bound to the given local endpoint and listening for incoming connections using the |
40 given backlog. |
42 given backlog. |
41 |
43 |
42 endpoint - local Endpoint to bind() to. Usually, it is enough to just specify the port. |
44 endpoint - local Endpoint to bind() to. Usually, it is enough to just specify the port. |
43 af - the socket address family to use (one of qmsk.net.socket.constants.AF_*) |
|
44 listen_backlog - backlog length argument to use for socket.listen() |
45 listen_backlog - backlog length argument to use for socket.listen() |
|
46 family - (optional) address family to use if no endpoint is given |
45 |
47 |
|
48 Note that as a special case, it is possible to construct a service without an Endpoint (i.e. None). |
|
49 In this case, there will be no socket.bind() call, instead, a socket is created with the given address |
|
50 family (which *MUST* be given), and .listen() causes the OS to pick a local address to use. |
46 |
51 |
47 This will raise an error if the bind() or listen() operations fail. |
52 This will raise an error if the bind() or listen() operations fail. |
48 """ |
53 """ |
49 |
54 |
50 # construct a suitable socket bound to the given endpoint |
55 # construct a suitable socket bound to the given endpoint |
51 self._init_endpoint(endpoint, af, socket.SOCK_STREAM) |
56 self._init_endpoint(endpoint, family=family) |
52 |
57 |
53 # make us listen |
58 # make us listen |
54 self._listen(listen_backlog) |
59 self._listen(listen_backlog) |
55 |
60 |
56 # ok, great |
61 # ok, great |
80 class Client (socket.Client, client.Client) : |
85 class Client (socket.Client, client.Client) : |
81 """ |
86 """ |
82 An implementation of Client for TCP sockets. |
87 An implementation of Client for TCP sockets. |
83 """ |
88 """ |
84 |
89 |
85 def __init__ (self, connect_endpoint, af=socket.AF_UNSPEC, bind_endpoint=None) : |
90 _SOCKTYPE = socket.SOCK_STREAM |
|
91 |
|
92 def __init__ (self, connect_endpoint, bind_endpoint=None) : |
86 """ |
93 """ |
87 Construct a client, connecting to the given remote endpoint. |
94 Construct a client, connecting to the given remote endpoint. |
88 |
95 |
89 connect_endpoint - remote Endpoint to connect() to. |
96 connect_endpoint - remote Endpoint to connect() to. |
90 af - socket address family to use (one of qmsk.net.socket.constants.AF_*) |
|
91 bind_endpoint - (optional) local Endpoint to bind() to before connecting. |
97 bind_endpoint - (optional) local Endpoint to bind() to before connecting. |
92 |
98 |
93 """ |
99 """ |
94 |
100 |
95 # store |
101 # store |
96 self.connect_endpoint = connect_endpoint |
102 self.connect_endpoint = connect_endpoint |
97 self.af = af |
|
98 self.bind_endpoint = bind_endpoint |
103 self.bind_endpoint = bind_endpoint |
99 |
104 |
100 def connect (self, cls=Connection) : |
105 def connect (self, cls=Connection) : |
101 """ |
106 """ |
102 Perform the connect() operation, returning a tcp.Connection. |
107 Perform the connect() operation, returning a tcp.Connection. |
103 """ |
108 """ |
104 |
109 |
105 if self.bind_endpoint : |
110 if self.bind_endpoint : |
106 # construct a suitable local socket, bound to a specific endpoint |
111 # construct a suitable local socket, bound to a specific endpoint |
107 sock = self._bind_endpoint(self.bind_endpoint, self.af, socket.SOCK_STREAM) |
112 sock = self._bind_endpoint(self.bind_endpoint) |
108 |
113 |
109 # connect it to the remote endpoint |
114 # connect it to the remote endpoint |
110 self._connect_sock_endpoint(sock, self.connect_endpoint, self.af, socket.SOCK_STREAM) |
115 self._connect_sock_endpoint(sock, self.connect_endpoint) |
111 |
116 |
112 else : |
117 else : |
113 # let _init_connect_endpoint pick a socket to use |
118 # let _init_connect_endpoint pick a socket to use |
114 sock = self._connect_endpoint(self.connect_endpoint, self.af, socket.SOCK_STREAM) |
119 sock = self._connect_endpoint(self.connect_endpoint) |
115 |
120 |
116 # construct |
121 # construct |
117 return cls(sock) |
122 return cls(sock) |
118 |
123 |