author | Tero Marttila <terom@fixme.fi> |
Sat, 26 Sep 2009 16:39:20 +0300 | |
changeset 50 | da394bb715af |
parent 28 | 020c89baaa33 |
permissions | -rw-r--r-- |
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 |
Abstract byte-stream transport interface. |
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.transport import transport |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
6 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
7 |
class Stream (transport.Transport) : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
8 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
9 |
A byte stream oriented transport. |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
10 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
11 |
This provides a sequenced, reliable, full-duplex, connection-oriented byte stream. |
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 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
14 |
def read (self, iov) : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
15 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
16 |
Read and return up to `iov` bytes from this stream. This may return fewer bytes than requested. |
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 |
If the stream does not contain any more data (i.e. EOF), an empty string is returned. |
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 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
21 |
raise NotImplementedError() |
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 |
def readv (self, iovecs) : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
24 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
25 |
Attempt to read data into a sequence of iov's, returning a sequence of buffers with the read data. |
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 |
This may return fewer buffers than specified if there was not sufficient data to fill all buffers. |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
28 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
29 |
By default, this is simply implemented using read(), but an implementation may also provide a more |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
30 |
efficient version. |
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 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
33 |
ret = [] |
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 |
for iovec in iovecs : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
36 |
buf = self.read(iovec) |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
37 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
38 |
if buf : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
39 |
ret.append(buf) |
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 |
else : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
42 |
# EOF! This should not be returned by readv! |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
43 |
break |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
44 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
45 |
return ret |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
46 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
47 |
def write (self, buf) : |
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 |
Attempt to write the given data to this stream, returning the number of bytes written, which may be less |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
50 |
than the length of the buffer given. |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
51 |
""" |
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 |
raise NotImplementedError() |
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 |
def writev (self, iovecs) : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
56 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
57 |
Attempt to write data from the given sequence of buffers to this stream, returning the total number of |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
58 |
bytes written, which may be less than the total length of the buffers given. |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
59 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
60 |
By default, this is simply implemented using write(), but an implementation may also provide a more |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
61 |
efficient version. |
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 |
ret = 0 |
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 |
for buf in iovec : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
67 |
# send this buffer |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
68 |
buf_len = self.write(buf) |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
69 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
70 |
# count total bytes sent |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
71 |
ret += buf_len |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
72 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
73 |
if buf_len < len(buf) : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
74 |
# buffer was sent incompletely, do not try and send any more |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
75 |
break |
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 |
return ret |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
78 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
79 |
def close (eslf) : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
80 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
81 |
Close this stream, disallowing any more read/write operations. |
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 discards any unread data, but written data that has been buffered will still be sent. |
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 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
86 |
raise NotImplementedError() |
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 |
def abort (self) : |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
89 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
90 |
Close this stream immediately, invalidating it for future use. |
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 |
This discards any unread data, and may discard written data that has been buffered and not yet sent. This |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
93 |
should also ignore any close-related errors. |
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 |
By default, this is implemented using close(), but an implementation may also provide a more efficient |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
96 |
version. |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
97 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
98 |
XXX: remove default implementation? |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
99 |
""" |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
100 |
|
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
101 |
# XXX: ignore close-related errors? |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
102 |
self.close() |
020c89baaa33
[transport] initial TCP implementation
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
103 |