0
|
1 /*******************************************************************************
|
|
2
|
2
|
3 copyright: Copyright (c) 2004 Kris Bell. All rights reserved
|
0
|
4
|
2
|
5 license: BSD style: $(LICENSE)
|
0
|
6
|
2
|
7 version: Mar 2004 : Initial release
|
|
8 version: Jan 2005 : RedShodan patch for timeout query
|
|
9 version: Dec 2006 : Outback release
|
0
|
10
|
2
|
11 author: Kris, modified by Rick Richardson (May 2008)
|
|
12
|
|
13 *******************************************************************************/
|
0
|
14
|
|
15 module dreactor.transport.AsyncSocketConduit;
|
|
16
|
|
17 private import tango.time.Time;
|
|
18
|
12
|
19 public import tango.io.device.Conduit;
|
0
|
20
|
|
21 private import tango.net.Socket;
|
|
22
|
|
23 /*******************************************************************************
|
|
24
|
2
|
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.
|
0
|
28
|
2
|
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 *******************************************************************************/
|
0
|
34
|
|
35 class AsyncSocketConduit : Conduit
|
|
36 {
|
3
|
37 package Socket socket_;
|
0
|
38
|
2
|
39 /***********************************************************************
|
|
40
|
|
41 Create a streaming Internet Socket
|
0
|
42
|
2
|
43 ***********************************************************************/
|
0
|
44
|
2
|
45 this ()
|
|
46 {
|
|
47 this (SocketType.STREAM, ProtocolType.TCP);
|
|
48 }
|
0
|
49
|
2
|
50 /***********************************************************************
|
0
|
51
|
2
|
52 Create an Internet Socket. Used by subclasses and by
|
|
53 ServerSocket; the latter via method allocate() below
|
|
54
|
|
55 ***********************************************************************/
|
0
|
56
|
2
|
57 protected this (SocketType type, ProtocolType protocol, bool create=true)
|
|
58 {
|
3
|
59 socket_ = new Socket (AddressFamily.INET, type, protocol, create);
|
|
60 socket_.blocking(false);
|
2
|
61 }
|
0
|
62
|
2
|
63 /***********************************************************************
|
0
|
64
|
2
|
65 Return the name of this device
|
0
|
66
|
2
|
67 ***********************************************************************/
|
0
|
68
|
2
|
69 override char[] toString()
|
|
70 {
|
|
71 return socket.toString;
|
|
72 }
|
0
|
73
|
2
|
74 /***********************************************************************
|
|
75
|
|
76 Return the socket wrapper
|
0
|
77
|
2
|
78 ***********************************************************************/
|
0
|
79
|
2
|
80 Socket socket ()
|
|
81 {
|
|
82 return socket_;
|
|
83 }
|
0
|
84
|
2
|
85 /***********************************************************************
|
|
86
|
|
87 Return a preferred size for buffering conduit I/O
|
0
|
88
|
2
|
89 ***********************************************************************/
|
0
|
90
|
2
|
91 override uint bufferSize ()
|
|
92 {
|
|
93 return 1024 * 8;
|
|
94 }
|
0
|
95
|
2
|
96 /***********************************************************************
|
0
|
97
|
2
|
98 Models a handle-oriented device.
|
0
|
99
|
2
|
100 TODO: figure out how to avoid exposing this in the general
|
|
101 case
|
0
|
102
|
2
|
103 ***********************************************************************/
|
0
|
104
|
13
|
105 Handle fileHandle ()
|
2
|
106 {
|
|
107 return cast(Handle) socket_.fileHandle;
|
|
108 }
|
0
|
109
|
2
|
110 /***********************************************************************
|
0
|
111
|
2
|
112 Is this socket still alive?
|
|
113
|
|
114 ***********************************************************************/
|
0
|
115
|
2
|
116 override bool isAlive ()
|
|
117 {
|
|
118 return socket_.isAlive;
|
|
119 }
|
0
|
120
|
2
|
121 /***********************************************************************
|
0
|
122
|
2
|
123 Connect to the provided endpoint
|
0
|
124
|
2
|
125 ***********************************************************************/
|
0
|
126
|
2
|
127 AsyncSocketConduit connect (Address addr)
|
|
128 {
|
|
129 socket_.connect (addr);
|
|
130 return this;
|
|
131 }
|
0
|
132
|
2
|
133 /***********************************************************************
|
0
|
134
|
2
|
135 Bind the socket. This is typically used to configure a
|
|
136 listening socket (such as a server or multicast socket).
|
|
137 The address given should describe a local adapter, or
|
|
138 specify the port alone (ADDR_ANY) to have the OS assign
|
|
139 a local adapter address.
|
|
140
|
|
141 ***********************************************************************/
|
|
142
|
|
143 AsyncSocketConduit bind (Address address)
|
|
144 {
|
|
145 socket_.bind (address);
|
|
146 return this;
|
|
147 }
|
0
|
148
|
2
|
149 /**************************************************************************
|
|
150
|
|
151 Enable the socket for listening
|
0
|
152
|
2
|
153 **************************************************************************/
|
3
|
154 AsyncSocketConduit listen(int backlog = 255)
|
2
|
155 {
|
3
|
156 socket_.listen(backlog);
|
2
|
157 return this;
|
|
158 }
|
|
159
|
|
160 /***********************************************************************
|
0
|
161
|
2
|
162 Inform other end of a connected socket that we're no longer
|
|
163 available. In general, this should be invoked before close()
|
|
164 is invoked
|
|
165
|
|
166 The shutdown function shuts down the connection of the socket:
|
0
|
167
|
2
|
168 - stops receiving data for this socket. If further data
|
|
169 arrives, it is rejected.
|
0
|
170
|
2
|
171 - stops trying to transmit data from this socket. Also
|
|
172 discards any data waiting to be sent. Stop looking for
|
|
173 acknowledgement of data already sent; don't retransmit
|
|
174 if any data is lost.
|
0
|
175
|
2
|
176 ***********************************************************************/
|
0
|
177
|
2
|
178 AsyncSocketConduit shutdown ()
|
|
179 {
|
|
180 socket_.shutdown (SocketShutdown.BOTH);
|
|
181 return this;
|
|
182 }
|
0
|
183
|
2
|
184 /***********************************************************************
|
|
185
|
|
186 Release this AsyncSocketConduit
|
0
|
187
|
2
|
188 Note that one should always disconnect a AsyncSocketConduit
|
|
189 under normal conditions, and generally invoke shutdown
|
|
190 on all connected sockets beforehand
|
0
|
191
|
2
|
192 ***********************************************************************/
|
0
|
193
|
2
|
194 override void detach ()
|
|
195 {
|
|
196 socket_.detach;
|
|
197 }
|
|
198
|
|
199 /***********************************************************************
|
0
|
200
|
2
|
201 Read content from the socket.
|
|
202
|
|
203 Returns the number of bytes read from the socket, or
|
|
204 IConduit.Eof where there's no more content available
|
3
|
205
|
|
206 Return IConduit.Eof if there is an error with the socket.
|
0
|
207
|
2
|
208 ***********************************************************************/
|
|
209 override uint read (void[] dst)
|
|
210 {
|
3
|
211 // invoke the actual read op
|
|
212 return socket_.receive(dst);
|
2
|
213 }
|
|
214
|
3
|
215
|
2
|
216 /***********************************************************************
|
0
|
217
|
2
|
218 Callback routine to write the provided content to the
|
3
|
219 socket.
|
2
|
220 ***********************************************************************/
|
0
|
221
|
2
|
222 override uint write (void[] src)
|
|
223 {
|
3
|
224 return socket_.send (src);
|
2
|
225 }
|
3
|
226 }
|
0
|
227
|