Mercurial > projects > dreactor
comparison dreactor/transport/AsyncSocketConduit.d @ 0:7a315154bf5e
Initial commit
author | rick@minifunk |
---|---|
date | Sun, 08 Jun 2008 01:45:38 -0400 |
parents | |
children | d3374d553986 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:7a315154bf5e |
---|---|
1 /******************************************************************************* | |
2 | |
3 copyright: Copyright (c) 2004 Kris Bell. All rights reserved | |
4 | |
5 license: BSD style: $(LICENSE) | |
6 | |
7 version: Mar 2004 : Initial release | |
8 version: Jan 2005 : RedShodan patch for timeout query | |
9 version: Dec 2006 : Outback release | |
10 | |
11 author: Kris, modified by Rick Richardson (May 2008) | |
12 | |
13 *******************************************************************************/ | |
14 | |
15 module dreactor.transport.AsyncSocketConduit; | |
16 | |
17 private import tango.time.Time; | |
18 | |
19 public import tango.io.Conduit; | |
20 | |
21 private import tango.net.Socket; | |
22 | |
23 /******************************************************************************* | |
24 | |
25 A wrapper around the bare Socket to implement the IConduit abstraction | |
26 and add socket-specific functionality specifically for multiplexing via | |
27 poll and the ilk. | |
28 | |
29 AsyncSocketConduit data-transfer is typically performed in conjunction with | |
30 an IBuffer, but can happily be handled directly using void array where | |
31 preferred | |
32 | |
33 *******************************************************************************/ | |
34 | |
35 class AsyncSocketConduit : Conduit | |
36 { | |
37 package Socket socket_; | |
38 | |
39 /*********************************************************************** | |
40 | |
41 Create a streaming Internet Socket | |
42 | |
43 ***********************************************************************/ | |
44 /* overriding the enum from the IConduit interface */ | |
45 enum : uint | |
46 { | |
47 Eof = uint.max, /// the End-of-Flow identifer | |
48 Err = uint.max -1 // some error ocurred, Should disconnect | |
49 } | |
50 | |
51 this () | |
52 { | |
53 this (SocketType.STREAM, ProtocolType.TCP); | |
54 } | |
55 | |
56 /*********************************************************************** | |
57 | |
58 Create an Internet Socket. Used by subclasses and by | |
59 ServerSocket; the latter via method allocate() below | |
60 | |
61 ***********************************************************************/ | |
62 | |
63 protected this (SocketType type, ProtocolType protocol, bool create=true) | |
64 { | |
65 socket_ = new Socket (AddressFamily.INET, type, protocol, create); | |
66 } | |
67 | |
68 /*********************************************************************** | |
69 | |
70 Return the name of this device | |
71 | |
72 ***********************************************************************/ | |
73 | |
74 override char[] toString() | |
75 { | |
76 return socket.toString; | |
77 } | |
78 | |
79 /*********************************************************************** | |
80 | |
81 Return the socket wrapper | |
82 | |
83 ***********************************************************************/ | |
84 | |
85 Socket socket () | |
86 { | |
87 return socket_; | |
88 } | |
89 | |
90 /*********************************************************************** | |
91 | |
92 Return a preferred size for buffering conduit I/O | |
93 | |
94 ***********************************************************************/ | |
95 | |
96 override uint bufferSize () | |
97 { | |
98 return 1024 * 8; | |
99 } | |
100 | |
101 /*********************************************************************** | |
102 | |
103 Models a handle-oriented device. | |
104 | |
105 TODO: figure out how to avoid exposing this in the general | |
106 case | |
107 | |
108 ***********************************************************************/ | |
109 | |
110 override Handle fileHandle () | |
111 { | |
112 return cast(Handle) socket_.fileHandle; | |
113 } | |
114 | |
115 /*********************************************************************** | |
116 | |
117 Is this socket still alive? | |
118 | |
119 ***********************************************************************/ | |
120 | |
121 override bool isAlive () | |
122 { | |
123 return socket_.isAlive; | |
124 } | |
125 | |
126 /*********************************************************************** | |
127 | |
128 Connect to the provided endpoint | |
129 | |
130 ***********************************************************************/ | |
131 | |
132 AsyncSocketConduit connect (Address addr) | |
133 { | |
134 socket_.connect (addr); | |
135 return this; | |
136 } | |
137 | |
138 /*********************************************************************** | |
139 | |
140 Bind the socket. This is typically used to configure a | |
141 listening socket (such as a server or multicast socket). | |
142 The address given should describe a local adapter, or | |
143 specify the port alone (ADDR_ANY) to have the OS assign | |
144 a local adapter address. | |
145 | |
146 ***********************************************************************/ | |
147 | |
148 AsyncSocketConduit bind (Address address) | |
149 { | |
150 socket_.bind (address); | |
151 return this; | |
152 } | |
153 | |
154 /*********************************************************************** | |
155 | |
156 Inform other end of a connected socket that we're no longer | |
157 available. In general, this should be invoked before close() | |
158 is invoked | |
159 | |
160 The shutdown function shuts down the connection of the socket: | |
161 | |
162 - stops receiving data for this socket. If further data | |
163 arrives, it is rejected. | |
164 | |
165 - stops trying to transmit data from this socket. Also | |
166 discards any data waiting to be sent. Stop looking for | |
167 acknowledgement of data already sent; don't retransmit | |
168 if any data is lost. | |
169 | |
170 ***********************************************************************/ | |
171 | |
172 AsyncSocketConduit shutdown () | |
173 { | |
174 socket_.shutdown (SocketShutdown.BOTH); | |
175 return this; | |
176 } | |
177 | |
178 /*********************************************************************** | |
179 | |
180 Release this AsyncSocketConduit | |
181 | |
182 Note that one should always disconnect a AsyncSocketConduit | |
183 under normal conditions, and generally invoke shutdown | |
184 on all connected sockets beforehand | |
185 | |
186 ***********************************************************************/ | |
187 | |
188 override void detach () | |
189 { | |
190 socket_.detach; | |
191 | |
192 // deallocate if this came from the free-list, | |
193 // otherwise just wait for the GC to handle it | |
194 if (fromList) | |
195 deallocate (this); | |
196 } | |
197 | |
198 /*********************************************************************** | |
199 | |
200 Read content from the socket. | |
201 | |
202 Returns the number of bytes read from the socket, or | |
203 IConduit.Eof where there's no more content available | |
204 | |
205 Note that a timeout is equivalent to Eof. Isolating | |
206 a timeout condition can be achieved via hadTimeout() | |
207 | |
208 Note also that a zero return value is not legitimate; | |
209 such a value indicates Eof | |
210 | |
211 ***********************************************************************/ | |
212 | |
213 override uint read (void[] dst) | |
214 { | |
215 return read (dst, (void[] dst){return socket_.receive(dst);}); | |
216 } | |
217 | |
218 /*********************************************************************** | |
219 | |
220 Callback routine to write the provided content to the | |
221 socket. This will stall until the socket responds in | |
222 some manner. Returns the number of bytes sent to the | |
223 output, or IConduit.Eof if the socket cannot write. | |
224 | |
225 ***********************************************************************/ | |
226 | |
227 override uint write (void[] src) | |
228 { | |
229 int count = socket_.send (src); | |
230 if (count == 0) | |
231 count = Eof; | |
232 else if (count < 0) | |
233 count = Err; | |
234 return count; | |
235 } | |
236 | |
237 /*********************************************************************** | |
238 | |
239 Internal routine to handle socket read under a timeout. | |
240 Note that this is synchronized, in order to serialize | |
241 socket access | |
242 | |
243 ***********************************************************************/ | |
244 | |
245 package final uint read (void[] dst, int delegate(void[]) dg) | |
246 { | |
247 // invoke the actual read op | |
248 int count = dg (dst); | |
249 if (count == 0) | |
250 return Eof; | |
251 else if (count < 0) | |
252 return Err; | |
253 | |
254 return count; | |
255 } | |
256 | |
257 } | |
258 |