I had a similar issue managing file uploads.
Firstly, see this post. As you are experiencing SocketException's, it's likely because too many connections are open.
To manage this, I built a class to manage the number of active operations while allowing multiple http calls to run concurrently. If you need these to finish in a particular order, you may want to combine this method with Future.wait().
This method relies on a StreamController to handle the http responses. Review the StreamController class documentation as there are several events (not used below) that you can listen to which may be helpful.
To use the class below (in simple terms):
- Declare the DownloadManager() in your main class/Widget
 
- Call the 
download() function 
download() creates a StreamController and starts to loop through the url's 
- The number of concurrent downloads is controlled via 
_maxActiveConnections 
- The loop will skip when 
_activeConnections == _maxActiveConnections 
- Once the loop ends, the function will wait for any remaining http requests to complete
 
- After the 
await downloadStream.done is complete, return your result or do whatever you need to with the result. 
import 'dart:async';
import 'dart:math' as math;
import 'package:http/http.dart' as http;
import 'package:flutter/services.dart';
class MyWidgetClass {
  DownloadManager downloadManager = DownloadManager();
  Future<bool> downloadZip(List<String> urls) async {
    final result = await downloadManager.download(urls);
    return result;
  }
}
class DownloadManager {
  /// Max number of http calls allowed at any time
  final _maxActiveConnections = 5;
  /// Time before retries when waiting for a free connection
  final _waitDuration = const Duration(milliseconds: 250);
  /// Current index to be uploaded when the downloader is [_enabled]
  int _index = 0;
  /// The number of connections currently active
  int _activeConnections = 0;
  /// Allow additional http calls to be added to the queue
  bool get _enabled => _activeConnections < _maxActiveConnections;
  /// Track the number of successful downloads (optional, useful if you need to
  /// know if all downloads are completed successfully)
  int _successCount = 0;
  /// the urls.length value
  int _totalDownloads = 0;
  /// number of http operations that have completed
  int _downloadsCompleted = 0;
  Future<bool> download(List<String> urls) async {
    _totalDownloads = urls.length;
    _downloadsCompleted = 0;
    _activeConnections = 0;
    _index = 0;
    _successCount = 0;
    // declare your encoder here
    // dynamic exampleZipEncoder = ...;
    // declare a Uint8List stream
    final downloadStream = StreamController<Uint8List?>();
    // listens to the http responses as they return
    downloadStream.stream.listen(
      // Fired when a download is finished
      (Uint8List? event) {
        print('Success!');
        if (event != null) {
          // Add bytes to the zip encoder
          //  exampleZipEncoder.add(event);
          _successCount++;
        }
        _setActiveConnections(-1);
      },
      onError: (error) {
        print('Error! $error');
        // Handle case when http fails
        _setActiveConnections(-1);
      },
    );
    // Run the downloads when _enabled = true
    while (_index < urls.length) {
      if (_enabled) {
        _bytesForFileAtUrl(urls[_index], downloadStream);
        _index++;
        _setActiveConnections(1);
      }
      await Future.delayed(_waitDuration);
    }
    // waits for all/any remaining http's to complete
    await downloadStream.done;
    // Close the zip encoder here, or you can add it to the StreamController
    // done event listener
    // await exampleZipEncoder.close();
    // return exampleZipEncoder;
    return _successCount == urls.length;
  }
  /// Handle download of a file
  Future<void> _bytesForFileAtUrl(String url, StreamController stream) async {
    try {
      http.Response response = await http.get(Uri(path: url));
      if (response.bodyBytes.isNotEmpty) {
        stream.add(response.bodyBytes);
      } else {
        stream.addError('Error: ${response.statusCode}');
      }
    } catch (e) {
      stream.addError('$e');
    }
    _downloadsCompleted++;
    // once all files have been downloaded, close the stream
    if (_downloadsCompleted == _totalDownloads) {
      stream.close();
    }
  }
  /// Increments/Decrements the number of [_activeConnections]
  void _setActiveConnections(int change) =>
      _activeConnections = math.max(0, _activeConnections + change);
}