Implementing Network Communication with DotNetty

Introduction

This article introduces how to implement network communication using DotNetty.

1. Program Design

Using the third-party library DotNetty to implement the host computer client. Official website: https://github.com/Azure/DotNetty/ Keywords: high performance, ease of use

DotNetty Architecture

The overall architecture of DotNetty can be divided into the following four parts:

  • Channel: The channel acts as a bridge between business logic and network logic. In DotNetty, all network data is transmitted through channels.
  • EventLoop: An event loop is a single thread used to handle specific types of events. Each EventLoop is bound to a Selector to monitor events of interest on channels. When an event occurs, the EventLoop is awakened to handle it.
  • ChannelPipeline: The channel pipeline is a series of handler chains used to process incoming and outgoing data streams. In DotNetty, all data passes through this pipeline, where multiple handlers can be added to implement business logic.
  • ChannelHandlerContext: The channel handler context contains all state information of the current channel. Each ChannelHandlerContext is associated with an EventLoop. When processing bussiness logic, data can be sent and the current channel state can be obtained through ChannelHandlerContext.

Important Components

  • Transport: Transport layer module for handling network connections of different protocols.
  • Codec: Codec module for encoding and decoding messages.
  • Handler: Handler module for implementing specific business logic.
  • Bootstrap: Bootstrap module for configuring and starting applications.

How to Choose Architecture and Components?

Review Chapter 1 to understand our requirements. We receive hexadecimal bytes; the first 2 bytes indicate the length of received content. The protocol specifies a maximum command size of 1KB (1024 bytes). We can configure the parsing rules via Bootstrap, then associate ChannelHandlerContext with EventLoop to recieve data, and use Channel to send data.

Here, we need to implement a client. We need to design three interfaces, one event, and two classes.

  • Interfaces: connect to server, disconnect from server, send content to server.
  • Event: receive content from server event.
  • Implementation classes:
    • Channel class for receiving content.
    • Client class implementing interfaces and event content, including parsing rules.

Future optimizations include managing multiple clients for multiple server connnections in the client, solving the timeout issue when connecting to a non-existent server IP (Ping function), etc. These will be provided in a complete solution in Chapter 5.

2. Code

NuGet package to add:

<PackageReference Include="DotNetty.Handlers" Version="0.7.6" />

Channel handler class:

/// <summary>
/// TCP channel handler
/// </summary>
internal class TcpChannelHandler : SimpleChannelInboundHandler<object>
{
    private TcpSocketClient _client;

    /// <summary>
    /// Constructor
    /// </summary>
    /// <param name="client">TCP client</param>
    public TcpChannelHandler(TcpSocketClient client)
    {
        _client = client;
    }

    /// <summary>
    /// Called after channel is connected
    /// </summary>
    /// <param name="context">Channel handler context</param>
    public override void ChannelActive(IChannelHandlerContext context)
    {
        _client.Client = context.Channel.Id.AsShortText();
        _client.Connected = true;
    }

    /// <summary>
    /// Called when channel read is complete
    /// </summary>
    /// <param name="context">Channel handler context</param>
    public override void ChannelReadComplete(IChannelHandlerContext context)
    {
        context.Flush();
    }
}

Tags: DotNetty Network Communication tcp C# .NET

Posted on Wed, 14 Oct 2026 16:50:15 +0000 by Fredix