OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 import "dart:async"; | |
6 import "dart:io"; | |
7 import "dart:typed_data"; | |
8 | |
9 import "package:async_helper/async_helper.dart"; | |
10 import "package:expect/expect.dart"; | |
11 | |
12 class FutureExpect { | |
13 static Future check(Future result, check) => | |
14 result.then((value) => check(value)); | |
15 static Future throws(Future result) => | |
16 result.then((value) { | |
17 throw new ExpectException( | |
18 "FutureExpect.throws received $value instead of an exception"); | |
19 }, onError: (_) => null); | |
20 } | |
21 | |
22 testDatagramSocketOptions() { | |
23 test(address) { | |
24 asyncStart(); | |
25 RawDatagramSocket.bind(address, 0).then((socket) { | |
26 Expect.isTrue(socket.multicastLoopback); | |
27 Expect.equals(1, socket.multicastHops); | |
28 Expect.throws(() => socket.multicastInterface); | |
29 Expect.isFalse(socket.broadcastEnabled); | |
30 | |
31 socket.multicastLoopback = false; | |
32 socket.multicastHops = 4; | |
33 socket.broadcastEnabled = true; | |
34 Expect.isFalse(socket.multicastLoopback); | |
35 Expect.equals(4, socket.multicastHops); | |
36 Expect.throws(() => socket.multicastInterface = null); | |
37 Expect.isTrue(socket.broadcastEnabled); | |
38 | |
39 socket.multicastLoopback = true; | |
40 socket.multicastHops = 1; | |
41 socket.broadcastEnabled = false; | |
42 Expect.isTrue(socket.multicastLoopback); | |
43 Expect.equals(1, socket.multicastHops); | |
44 Expect.throws(() => socket.multicastInterface); | |
45 Expect.isFalse(socket.broadcastEnabled); | |
46 asyncEnd(); | |
47 }); | |
48 } | |
49 | |
50 test(InternetAddress.LOOPBACK_IP_V4); | |
51 test(InternetAddress.ANY_IP_V4); | |
52 test(InternetAddress.LOOPBACK_IP_V6); | |
53 test(InternetAddress.ANY_IP_V6); | |
54 } | |
55 | |
56 testDatagramSocketReuseAddress() { | |
57 test(address, reuseAddress) { | |
58 asyncStart(); | |
59 RawDatagramSocket.bind( | |
60 address, 0, reuseAddress: reuseAddress).then((socket) { | |
61 if (reuseAddress) { | |
62 RawDatagramSocket.bind(address, socket.port) | |
63 .then((s) => Expect.isTrue(s is RawDatagramSocket)) | |
64 .then(asyncSuccess); | |
65 } else { | |
66 FutureExpect.throws(RawDatagramSocket.bind(address, socket.port)) | |
67 .then(asyncSuccess); | |
68 } | |
69 }); | |
70 } | |
71 | |
72 test(InternetAddress.LOOPBACK_IP_V4, true); | |
73 test(new InternetAddress('224.0.0.0'), true); | |
74 test(InternetAddress.LOOPBACK_IP_V4, false); | |
75 test(new InternetAddress('224.0.0.0'), false); | |
76 test(InternetAddress.LOOPBACK_IP_V6, true); | |
77 test(new InternetAddress("ff11::0"), true); | |
78 test(InternetAddress.LOOPBACK_IP_V6, false); | |
79 test(new InternetAddress("ff11::0"), false); | |
80 } | |
81 | |
82 testBroadcast() { | |
83 test(bindAddress, broadcastAddress, enabled) { | |
84 asyncStart(); | |
85 Future.wait([RawDatagramSocket.bind(bindAddress, 0), | |
86 RawDatagramSocket.bind(bindAddress, 0)]).then((values) { | |
87 var broadcastTimer; | |
88 var sender = values[0]; | |
89 var receiver = values[1]; | |
90 sender.broadcastEnabled = enabled; | |
91 receiver.listen((event) { | |
92 if (event == RawSocketEvent.READ) { | |
93 Expect.isTrue(enabled); | |
94 sender.close(); | |
95 receiver.close(); | |
96 broadcastTimer.cancel(); | |
97 asyncEnd(); | |
98 } | |
99 }); | |
100 | |
101 int sendCount = 0; | |
102 send(_) { | |
103 sender.send(new Uint8List(1), broadcastAddress, receiver.port); | |
104 sendCount++; | |
105 if (!enabled && sendCount == 50) { | |
106 sender.close(); | |
107 receiver.close(); | |
108 broadcastTimer.cancel(); | |
109 asyncEnd(); | |
110 } | |
111 } | |
112 broadcastTimer = new Timer.periodic(new Duration(milliseconds: 10), send); | |
113 }); | |
114 } | |
115 | |
116 var broadcast = new InternetAddress("255.255.255.255"); | |
117 test(InternetAddress.ANY_IP_V4, broadcast, false); | |
118 test(InternetAddress.ANY_IP_V4, broadcast, true); | |
119 } | |
120 | |
121 testLoopbackMulticast() { | |
122 test(bindAddress, multicastAddress, enabled) { | |
123 asyncStart(); | |
124 Future.wait([RawDatagramSocket.bind(bindAddress, 0), | |
125 RawDatagramSocket.bind(bindAddress, 0)]).then((values) { | |
126 var senderTimer; | |
127 var sender = values[0]; | |
128 var receiver = values[1]; | |
129 | |
130 sender.join(multicastAddress); | |
131 receiver.join(multicastAddress); | |
132 receiver.multicastLoopback = false; | |
133 sender.multicastLoopback = enabled; | |
134 | |
135 receiver.listen((event) { | |
136 if (event == RawSocketEvent.READ) { | |
137 Expect.isTrue(enabled); | |
138 sender.close(); | |
139 receiver.close(); | |
140 senderTimer.cancel(); | |
141 asyncEnd(); | |
142 } | |
143 }); | |
144 | |
145 int sendCount = 0; | |
146 send(_) { | |
147 sender.send(new Uint8List(1), multicastAddress, receiver.port); | |
148 sendCount++; | |
149 if (!enabled && sendCount == 50) { | |
150 sender.close(); | |
151 receiver.close(); | |
152 senderTimer.cancel(); | |
153 asyncEnd(); | |
154 } | |
155 } | |
156 senderTimer = new Timer.periodic(new Duration(milliseconds: 10), send); | |
157 }); | |
158 } | |
159 | |
160 test(InternetAddress.ANY_IP_V4, new InternetAddress("224.0.0.0"), true); | |
161 test(InternetAddress.ANY_IP_V4, new InternetAddress("224.0.0.0"), false); | |
162 test(InternetAddress.ANY_IP_V6, new InternetAddress("ff11::0"), true); | |
163 test(InternetAddress.ANY_IP_V6, new InternetAddress("ff11::0"), false); | |
164 } | |
165 | |
166 testSendReceive(InternetAddress bindAddress) { | |
167 asyncStart(); | |
168 | |
169 var total = 10; | |
170 | |
171 int receivedSeq = 0; | |
172 var ackSeq = 0; | |
173 Timer ackTimer; | |
174 | |
175 Future.wait([RawDatagramSocket.bind(bindAddress, 0), | |
176 RawDatagramSocket.bind(bindAddress, 0)]).then((values) { | |
177 var sender = values[0]; | |
178 var receiver = values[1]; | |
179 if (bindAddress.isMulticast) { | |
180 sender.multicastLoopback = true; | |
181 receiver.multicastLoopback = true; | |
182 sender.join(bindAddress); | |
183 receiver.join(bindAddress); | |
184 } | |
185 | |
186 UInt8List createDataPackage(int seq) { | |
187 var data = new Uint8List(1000); | |
188 (new ByteData.view(data.buffer, 0, 4)).setUint32(0, seq); | |
189 return data; | |
190 } | |
191 | |
192 UInt8List createAckPackage(int seq) { | |
193 var data = new Uint8List(4); | |
194 new ByteData.view(data.buffer, 0, 4).setUint32(0, seq); | |
195 return data; | |
196 } | |
197 | |
198 int packageSeq(Datagram datagram) => | |
199 new ByteData.view(datagram.data.buffer).getUint32(0); | |
200 | |
201 void sendData(int seq) { | |
202 // Send a datagram acknowledging the received sequence. | |
203 sender.send(createDataPackage(seq), bindAddress, receiver.port); | |
Anders Johnsen
2013/11/29 12:36:54
Check send return value.
Søren Gjesse
2013/12/12 11:38:46
Done.
| |
204 } | |
205 | |
206 void sendAck(address, port) { | |
207 // Send a datagram acknowledging the received sequence. | |
208 receiver.send(createAckPackage(receivedSeq), address, port); | |
209 // Start a "long" timer for more data. | |
210 if (ackTimer != null) ackTimer.cancel(); | |
211 ackTimer = new Timer.periodic( | |
212 new Duration(milliseconds: 100), (_) => sendAck(address, port)); | |
213 } | |
214 | |
215 sender.listen((event) { | |
216 switch (event) { | |
217 case RawSocketEvent.READ: | |
218 var datagram = sender.receive(); | |
219 if (datagram != null) { | |
220 Expect.equals(datagram.port, receiver.port); | |
221 if (!bindAddress.isMulticast) { | |
222 Expect.equals(receiver.address, datagram.address); | |
223 } | |
224 ackSeq = packageSeq(datagram); | |
225 if (ackSeq < total) { | |
226 sender.writeEventsEnabled = true; | |
227 } else { | |
228 sender.close(); | |
229 receiver.close(); | |
230 ackTimer.cancel(); | |
231 asyncEnd(); | |
232 } | |
233 } | |
234 break; | |
235 case RawSocketEvent.WRITE: | |
236 // Send the next package. | |
237 sendData(ackSeq + 1); | |
238 break; | |
239 case RawSocketEvent.CLOSED: | |
240 break; | |
241 default: | |
242 throw "Unexpected event $event"; | |
243 } | |
244 }); | |
245 | |
246 receiver.writeEventsEnabled = false; | |
247 receiver.listen((event) { | |
248 switch (event) { | |
249 case RawSocketEvent.READ: | |
250 var datagram = receiver.receive(); | |
251 if (datagram != null) { | |
252 Expect.equals(datagram.port, sender.port); | |
253 if (!bindAddress.isMulticast) { | |
254 Expect.equals(receiver.address, datagram.address); | |
255 } | |
256 var seq = packageSeq(datagram); | |
257 if (seq == receivedSeq + 1) { | |
258 receivedSeq = seq; | |
259 sendAck(bindAddress, sender.port); | |
260 } | |
261 } | |
262 break; | |
263 case RawSocketEvent.WRITE: | |
264 throw "Unexpected WRITE"; | |
265 break; | |
266 case RawSocketEvent.CLOSED: | |
267 break; | |
268 default: | |
269 throw "Unexpected event $event"; | |
270 } | |
271 }); | |
272 }); | |
273 } | |
274 | |
275 | |
276 main() { | |
277 testDatagramSocketOptions(); | |
278 testDatagramSocketReuseAddress(); | |
279 testBroadcast(); | |
280 testLoopbackMulticast(); | |
281 testSendReceive(InternetAddress.LOOPBACK_IP_V4); | |
282 testSendReceive(new InternetAddress("224.0.0.0")); | |
283 testSendReceive(InternetAddress.LOOPBACK_IP_V6); | |
284 testSendReceive(new InternetAddress("ff11::114")); | |
285 } | |
OLD | NEW |