Providing libtorrent through a C++ library for use in .NET on Windows, Linux, macOS and Android.
Add csdl
to the project via NuGet and create a single TorrentClient
instance.
This will usually be static
(or singleton if using a dependency container), and a TorrentClientConfig
can be passed in the constructor to configure the client.
// create a new TorrentClient instance, optionally passing in the configuration
var options = new TorrentClientConfig
{
ForceEncryption = true,
MaxConnections = 500
};
using var client = new TorrentClient(options);
// bonus: there is also an event handler that can be subscribed to if more information is wanted.
client.AlertRaised += (sender, args) =>
{
// args can be checked against all classes in the csdl.Alerts namespace for more properties.
Console.WriteLine(args.Message);
};
.torrent files can be parsed either by passing in a file path or a byte array containing the file contents to the TorrentInfo
class, and the instance will be populated accordingly.
Some metadata can be accessed from the TorrentInfo
instance, such as the name of the torrent and a list of files contained within it.
var filePath = "path/to/torrent/file.torrent";
var torrentInfo = new TorrentInfo(filePath);
// get the name and list of files
Console.WriteLine($"Name: {torrentInfo.Name}");
Console.WriteLine("Files:");
foreach (var file in torrentInfo.Files)
{
Console.WriteLine($"- {file.Path} ({file.Size} bytes)");
}
After parsing a torrent file, it can be "attached" to the client to start downloading the files. Note this method will not start a download, but will prepare the client to download the files when Start
is called.
This method also has an overload allowing a custom save path to be specified. If not, the default save path will be used (client.DefaultDownloadPath
).
// this will be saved to DefaultDownloadPath.
var torrentManager = client.AttachTorrent(torrentInfo);
// the metadata can still be accessed but files have additional properties including their final destination and their download priority, which can be changed.
torrentManager.Files[0].Priority = TorrentFilePriority.DoNotDownload;
// after setting priorities, the download can begin (or resume if the torrent was previously started)
torrentManager.Start();
// if we want a progress update, we can request one
var progress = torrentManager.GetCurrentStatus();
if (progress.State == TorrentState.Finished)
{
torrentManager.Stop();
// when we want to "dispose" the manager, we can detach it from the client
client.DetachTorrent(torrentManager);
}
If we want to wait for the download to complete, a timer and a TaskCompletionSource
can be used to await the completion of the download.
void PerformDownload(TorrentClient client, TorrentInfo info, string savePath = null)
{
var torrentTransfer = new TaskCompletionSource();
var torrentManager = client.AttachTorrent(info, savePath);
torrentManager.Start();
using (new Timer(PerformProgressCheck, null, TimeSpan.Zero, TimeSpan.FromSeconds(1)))
{
await torrentTransfer.Task;
}
// at this point, the torrentManager has either finished downloading or seeding, and the poll has been stopped.
client.DetachTorrent(torrentManager);
return;
// this function polls the progress (makes a call to libtorrent) every second to check if the torrent has finished downloading
void PerformProgressCheck(object state)
{
if (torrentManager.GetCurrentStatus().State is TorrentState.Seeding or TorrentState.Finished)
{
torrentTransfer.SetResult();
}
}
}
The native libraries, csdl.Native
, are currently built for Windows, macOS and Linux for both x64 and arm64 architectures.
Android support is also provided by an optional package, csdl.Native.android which can be installed alongside csdl
to extend platform compatibility to Android 5.0+ devices with x86_64
, armeabi-v7a
and arm64-v8a
ABIs.