KermitClient provides the client-side Kermit session over a serial port for Windows and Linux.
KermitClientSessionKermitClientOptionsSerialPortTransportfromKermitCommon
using KermitClient;
using KermitCommon;
var transport = new SerialPortTransport("COM2", 115200);
var client = new KermitClientSession(
transport,
new KermitClientOptions
{
DownloadDirectory = Path.Combine(Environment.CurrentDirectory, "downloads"),
ResponseTimeoutMilliseconds = 5000,
MaxRetries = 5
});
await client.OpenAsync();On Linux, use a device path such as /dev/ttyUSB0 or /dev/ttyS0.
client.UploadProgressChanged += (_, e) =>
{
Console.WriteLine($"Upload {e.Progress.FileName}: {e.Progress.BytesTransferred}/{e.Progress.TotalBytes}");
};
client.UploadCompleted += (_, e) =>
{
Console.WriteLine($"Upload completed: {e.FullPath}");
};
await client.SendFileAsync(@"C:\temp\sample.txt");client.DownloadProgressChanged += (_, e) =>
{
Console.WriteLine($"Download {e.Progress.FileName}: {e.Progress.BytesTransferred}/{e.Progress.TotalBytes}");
};
client.DownloadCompleted += (_, e) =>
{
Console.WriteLine($"Downloaded to: {e.FullPath}");
};
var savedPath = await client.RequestFileAsync("remote.txt");
Console.WriteLine(savedPath);client.DirectoryListingReceived += (_, e) =>
{
Console.WriteLine($"Remote path: {e.RemotePath}");
foreach (var entry in e.Entries)
{
Console.WriteLine($"{(entry.IsDirectory ? "<DIR>" : "FILE ")} {entry.Name} {entry.Size}");
}
};
var entries = await client.ListRemoteDirectoryAsync(".");
Console.WriteLine($"Entries: {entries.Count}");client.WorkingDirectoryReceived += (_, e) =>
{
Console.WriteLine($"Remote path: {e.RemotePath}");
};
var remotePath = await client.GetRemoteWorkingDirectoryAsync();
Console.WriteLine(remotePath);client.ChangeDirectoryReceived += (_, e) =>
{
Console.WriteLine($"Changed to: {e.NewPath}");
};
var newPath = await client.ChangeRemoteDirectoryAsync("subfolder");
Console.WriteLine(newPath);
// Navigate up one level
var parentPath = await client.ChangeRemoteDirectoryAsync("..");
// Return to server root
var rootPath = await client.ChangeRemoteDirectoryAsync("/");client.MakeDirectoryReceived += (_, e) =>
{
Console.WriteLine($"Directory created: {e.CreatedPath}");
};
await client.MakeRemoteDirectoryAsync("reports/2026");Intermediate directories are created automatically (equivalent to mkdir -p). Paths are resolved relative to the current remote directory.
client.RemoveReceived += (_, e) =>
{
var kind = e.WasDirectory ? "directory" : "file";
Console.WriteLine($"Removed {kind}: {e.RemovedPath}");
};
// Remove a file
await client.RemoveRemoteAsync("old-report.txt");
// Remove an empty directory
await client.RemoveRemoteAsync("emptydir");If the path does not exist, or the directory is not empty, the server sends an error packet and RemoveRemoteAsync throws InvalidOperationException.
Every major Kermit command already exposes events from the shared base session:
SendInitReceived/SendInitSentFileHeaderReceived/FileHeaderSentFileAttributesReceived/FileAttributesSentDataReceived/DataSentEndOfFileReceived/EndOfFileSentBreakReceived/BreakSentAckReceived/AckSentNakReceived/NakSentErrorReceived/ErrorSentGenericCommandReceived/GenericCommandSentRemoteCommandReceived/RemoteCommandSentReceiveInitReceived/ReceiveInitSentTextHeaderReceived/TextHeaderSentPacketReceived/PacketSent
Example:
client.AckReceived += (_, e) =>
{
Console.WriteLine($"ACK seq={e.Packet.Sequence} msg={e.Message}");
};
client.ErrorReceived += (_, e) =>
{
Console.WriteLine($"ERROR: {e.Message}");
};Logging is shared from KermitCommon through NLog.
No extra client logger setup is required unless custom NLog configuration is desired.
await client.CloseAsync();
await client.DisposeAsync();- Open the session before sending or requesting files.
- Use
ListRemoteDirectoryAsync()to issue the remotelscommand. - Use
GetRemoteWorkingDirectoryAsync()to issue the remotepwdcommand. - Use
ChangeRemoteDirectoryAsync(path)to issue the remotecdcommand. - Use matching serial settings on client and server.
- Current implementation supports the core transfer flow and command events.
- Advanced Kermit options such as long packets and multi-packet windows are not yet implemented.