• Stars
    star
    152
  • Rank 244,685 (Top 5 %)
  • Language
    C#
  • Created over 6 years ago
  • Updated almost 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

An asynchronous variant of TcpClient and TcpListener for .NET Standard.

AsyncTcpClient & AsyncTcpListener

An asynchronous variant of TcpClient and TcpListener for .NET Standard.

NuGet

Building asynchronous solutions with TcpClient and TcpListener is complicated and it is easy to introduce bugs or miss critical features. These classes provide an easy solution for this task. Writing asynchronous TCP/IP clients and servers with these classes only requires the implementation of very basic callbacks. Alternatively, you can implement your connection logic in derived classes. In any case, you just have to read the received data from a buffer and send data back. All socket and stream interaction is hidden from you.

This also includes an asynchronous byte buffer that keeps all received bytes as they come in. Applications can dequeue as many bytes as they need without discarding what else was received. Dequeueing returns up to as many bytes as are available when called synchronously, or exactly the requested number of bytes when called asynchronously. The async method can be cancelled. This ensures that the code will never block irrecoverably.

A complete example of both implementation styles is provided in the application in this repository. Start reading at Program.cs.

Features

  • Awaitable (async) client connection
  • Awaitable (async) listener
  • Automatic reconnecting of the client on connection loss
  • Client: React on new connection
  • Client: React on closed connection
  • Client: React on received data
  • Client: Received data queue buffer, fetch as much data as you need when itโ€™s available
  • Just three small class files to add to your project (AsyncTcpClient, ByteBuffer, optional: AsyncTcpListener)

Whatโ€™s so hard about TcpClient?

โ€œThe TcpClient class provides simple methods for connecting, sending, and receiving stream data over a network in synchronous blocking mode.โ€ Reading from the network stream is a blocking operation. Once you decided that you need received data, your code will block until data was actually received. Your application will even deadlock if no data will ever be sent for some reason. While you can use the DataAvailable property to test that, you still need to poll it regularly, introducing additional load and delays.

While youโ€™re doing something else and not wait for received data, you will also not notice when the connection was closed remotely. Detecting this requires calling the Read method.

Add to this exception handling with special error codes for normal situations and things are getting complicated.

AsyncTcpClient and AsyncTcpListener take all that complexity out of the process, with the bonus of automatic client reconnecting and server-side client connection management. You just handle a new connection and/or received data, the rest is taken care of by these classes.

Client side

Usage

Derived class with overridden methods:

var client = new DemoTcpClient
{
    IPAddress = IPAddress.IPv6Loopback,
    Port = 12345,
    //AutoReconnect = true
};
await client.RunAsync();

AsyncTcpClient with callbacks:

var client = new AsyncTcpClient
{
    IPAddress = IPAddress.IPv6Loopback,
    Port = 12345,
    //AutoReconnect = true,
    ConnectedCallback = async (client, isReconnected) =>
    {
        // Custom connection logic
    },
    ReceivedCallback = async (client, count) =>
    {
        // Custom connection logic
    }
};
await client.RunAsync();

Close the client connection:

// This can be called from within a callback
client.Disconnect();

// This should only be called outside of RunAsync
client.Dispose();

OnConnected

Virtual method to override in derived classes:

protected virtual Task OnConnectedAsync(bool isReconnected)

Callback method:

public Func<AsyncTcpClient, bool, Task> ConnectedCallback { get; set; }

Called when the client has connected to the remote host. This method can implement the communication logic to execute when the connection was established. The connection will not be closed before this method completes.

OnClosed

Virtual method to override in derived classes:

protected virtual void OnClosed(bool remote)

Callback method:

public Action<AsyncTcpClient, bool> ClosedCallback { get; set; }

Called when the connection was closed.

Parameter remote: true, if the connection was closed by the remote host; false, if the connection was closed locally.

OnReceived

Virtual method to override in derived classes:

protected virtual Task OnReceivedAsync(int count)

Callback method:

public Func<AsyncTcpClient, int, Task> ReceivedCallback { get; set; }

Called when data was received from the remote host. This method can implement the communication logic to execute every time data was received. New data will not be received before this method completes.

Parameter count: The number of bytes that were received. The actual data is available through the ByteBuffer.

Server side

Usage

Generic class with type argument for derived client class:

var server = new AsyncTcpListener<DemoTcpServerClient>
{
    IPAddress = IPAddress.IPv6Any,
    Port = 12345
};
await server.RunAsync();

Non-generic AsyncTcpListener with callbacks:

var server = new AsyncTcpListener
{
    IPAddress = IPAddress.IPv6Any,
    Port = 12345,
    ClientConnectedCallback = tcpClient =>
        new AsyncTcpClient
        {
            ServerTcpClient = tcpClient,
            RemoteEndPoint = tcpClient.Client.RemoteEndPoint,
            ConnectedCallback = async (serverClient, isReconnected) =>
            {
                // Custom server logic
            },
            ReceivedCallback = async (serverClient, count) =>
            {
                // Custom server logic
            }
        }.RunAsync()
};
await server.RunAsync();

Stop the listener:

server.Stop(true);

Stop the listener but keep client connections open:

server.Stop(false);

OnClientConnected

Virtual method to override in derived classes:

protected virtual Task OnClientConnected(TcpClient tcpClient)

Callback method:

public Func<TcpClient, Task> ClientConnectedCallback { get; set; }

Called when a pending connection request was accepted. When this method completes, the client connection will be closed.

Parameter tcpClient: The TcpClient that represents the accepted connection.

Generic type parameter:

public class AsyncTcpListener<TClient>
    : AsyncTcpListener
    where TClient : AsyncTcpClient, new()

Instantiates a new AsyncTcpClient instance of the type TClient that runs the accepted connection. This implementation does not call the OnClientConnected callback method.

License

Permissive license

Copyright (c) 2018, Yves Goergen, https://unclassified.software

Copying and distribution of this file, with or without modification, are permitted provided the copyright notice and this notice are preserved. This file is offered as-is, without any warranty.

More Repositories

1

HyperVSwitch

Hyper-V Switch โ€“ A simple GUI to enable or disable Hyper-V without uninstallation, allowing the use of other virtualisation solutions.
C#
290
star
2

MultiSelectTreeView

A WPF TreeView control with support for multiple selection.
C#
181
star
3

msgpack.js

A minimal yet complete MessagePack implementation for JavaScript. msgpack.org[JavaScript]
JavaScript
143
star
4

T-Clock

Highly configurable Windows taskbar clock
C
41
star
5

NetRevisionTask

Injects the current VCS revision of a working directory in a custom format into a .NET assembly build. Based on the .NET Revision Tool, integrated as an MSBuild task, for .NET Framework and .NET Core.
C#
33
star
6

TxTranslation

Tx Translation & Localisation for .NET and WPF
C#
28
star
7

FieldLog

Fast and comprehensive logging tool for .NET applications
C#
21
star
8

EasyPdfSigning

Easy digital signing of PDF documents without rebuilding them. Allows multiple signing.
C#
19
star
9

NetDllExport

Exports static methods in a managed DLL as library functions that can be called from an unmanaged Windows application.
C#
19
star
10

TodoHighlighter

Visual Studio extension that places red boxes behind all the โ€œTODOโ€s in the editor window.
C#
19
star
11

NetRevisionTool

Injects the current VCS revision into a .NET assembly build.
C#
15
star
12

DotnetMakeDeb

Creates a .deb Debian binary package from a specification file through the dotnet CLI command or as standalone command-line tool.
C#
13
star
13

ViewModelKit

Makes WPF ViewModel classes smart by default.
C#
11
star
14

CecilExplorer

Mono.Cecil object model explorer
C#
9
star
15

MiniWebCompiler

Compiles JavaScript code and SCSS stylesheets for the web, in a simple and clean GUI for Windows. https://unclassified.software/apps/miniwebcompiler
C#
5
star
16

FlashConsoleWindow

Flashes the console window entry in the taskbar and changes the integrated progress bar (Windows Vista+).
C++
3
star
17

DeepConvert

Converts a data type to another data type, smarter than the standard Convert class, including collections and their items as well as object properties (duck typing). With special support for DateTime conversions.
C#
3
star
18

psbuild

Automated, local building of Visual Studio solutions and calling external tools like unit tests, source code commit, obfuscation, digitally signing, file publishing and transfer.
PowerShell
3
star
19

SettingsAdapterFactory

Generates dynamic types that implement an interface with properties that bind to a settings store and implement INotifyPropertyChanged.
C#
2
star
20

DotnetSshDeploy

Deploys websites and applications to SSH servers through the dotnet CLI command or as standalone command-line tool.
C#
2
star
21

Frontfire1

The Frontfire Web Frontend Framework offers essential styles and effects combined with a consistent set of interactive widgets and layout utilities.
JavaScript
2
star
22

GitRevisionTool

Prints out the current Git revision info of a working directory and automatically writes it into your .NET project for the build.
C#
1
star
23

NewMailNotification

Thunderbird new e-mail notification UI helper, designed to work with the Mailbox Alert add-on.
C#
1
star
24

GitInstaller

Installs or updates Git components on a developer computer. http://unclassified.software/apps/gitinstaller
C#
1
star