How to Send 254 HTTP Requests in Dart
It come across to me when I trying to develop a function that automatically find a specific service in local network, how to send multiple http request with minimum amount of time. In this blog, we'll explore different methods to send 254 HTTP requests in Dart, detailing their pros and cons.
1. Simple async
and await
The first thing come to mind is using the simple await
with http
package, which turn out to be simplest way to implement but slowest while trying to loop through all addresses.
import 'package:http/http.dart' as http;
void main() async {
for (int i = 1; i < 255; i++) {
try {
final response = await http
.get(Uri.parse('http://192.168.3.$i:80'))
.timeout(const Duration(
milliseconds: 500,
));
print(
'Response $i: ${response.body}',
);
} on TimeoutException {
print('Timeout');
}
}
}
Pros:
- Simplicity: Easy to understand and implement.
Cons:
- Slow: Each request waits for the previous one to complete, making it time-consuming. Took over 100 second to complete all scan.
2. Using async
without await
To improve speed, we can send requests without await
so that it can be processed concurrently by Dart.
import 'package:http/http.dart' as http;
void main() async {
for (int i = 1; i < 255; i++) {
http
.get(Uri.parse('http://192.168.3.$i:80'))
.timeout(const Duration(
milliseconds: 500,
))
.then(
(response) {
print('Response $i: ${response.body}');
},
).catchError(
(error) {
print(error.toString());
},
);
}
}
Pros:
- Faster: Requests are sent concurrently, significantly reducing overall time. Took only about 200 ms to complete, about 100 times faster than the first method.
Cons:
- Resource Intensive: As the amount of request grow it will more resource out of the app which could cause performance issue. However in this case it is not a big deal.
3. using Future
and Future.wait
.
To improve on method 2, we can use Future.wait
to encapsulation the code to a separate function.
import 'package:http/http.dart' as http;
Future<List<Uri>> getActiveIps() async {
List<Uri> activeIps = [];
final futures = List.generate(
254,
(index) => Uri.parse('http://192.168.3.${index + 1}:80'),
).map(
(uri) => http
.get(uri)
.then(
(response) => activeIps.add(uri),
)
.timeout(
const Duration(milliseconds: 500),
),
);
try {
await Future.wait(futures);
} catch (err) {
// Ingore
}
return activeIps;
}
void main() async {
getActiveIps().then((value) {
print(value);
});
}
Conclusion
For scanning a local network with only 254 IP addresses, method 3 is generally sufficient. However, for scanning larger networks or remote services, you may need to employ different techniques, such as batching requests or using isolates for parallel processing depending on the requirements. Choose the method that best fits your application's needs. Happy coding!