You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#:使用DotNetty搭建的Socket服务器无法正常接收客户端消息?

实现DotNetty服务器接收并展示客户端字符串消息

看起来你已经在写测试客户端了,不过代码好像没写完,我先帮你补全并格式化客户端代码,然后给你对应的DotNetty服务器实现,确保能正确接收并展示消息。

补全后的客户端代码

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

class ClientProgram
{
    static void Main(string[] args)
    {
        var ipAddress = "127.0.0.1";
        var port = 1232;
        using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        
        try
        {
            socket.Connect(new IPEndPoint(IPAddress.Parse(ipAddress), port));
            Console.WriteLine("已连接到服务器");
        }
        catch (SocketException se)
        {
            Console.WriteLine($"连接服务器失败:{se.Message}");
            return;
        }

        // 发送字符串消息
        byte[] forwardMessage = Encoding.Default.GetBytes("lol");
        socket.Send(forwardMessage);
        Console.WriteLine("消息已发送");

        // 关闭连接
        socket.Shutdown(SocketShutdown.Both);
    }
}

DotNetty服务器实现代码

要让服务器正确解析客户端发送的字符串,需要配置对应的字符串编解码器,同时自定义Handler来处理消息:

using DotNetty.Bootstrapping;
using DotNetty.Handlers.Codec.String;
using DotNetty.Transport.Channels;
using DotNetty.Transport.Channels.Sockets;
using System;
using System.Text;
using System.Threading.Tasks;

class ServerProgram
{
    static async Task Main(string[] args)
    {
        // 配置EventLoopGroup,bossGroup负责接收连接,workerGroup处理后续IO
        var bossGroup = new MultithreadEventLoopGroup(1);
        var workerGroup = new MultithreadEventLoopGroup();

        try
        {
            var bootstrap = new ServerBootstrap();
            bootstrap
                .Group(bossGroup, workerGroup)
                .Channel<TcpServerSocketChannel>()
                .Option(ChannelOption.SoBacklog, 100)
                .ChildHandler(new ActionChannelInitializer<IChannel>(channel =>
                {
                    var pipeline = channel.Pipeline;
                    // 关键:添加字符串解码器,编码要和客户端一致(这里用Encoding.Default)
                    pipeline.AddLast(new StringDecoder(Encoding.Default));
                    // 如果需要给客户端回复消息,添加字符串编码器
                    pipeline.AddLast(new StringEncoder(Encoding.Default));
                    // 添加自定义的消息处理Handler,用于打印收到的消息
                    pipeline.AddLast(new MessageDisplayHandler());
                }));

            // 绑定端口启动服务器
            var boundChannel = await bootstrap.BindAsync(IPAddress.Loopback, 1232);
            Console.WriteLine("DotNetty服务器已启动,等待客户端连接...");
            await boundChannel.CloseCompletion;
        }
        finally
        {
            // 优雅关闭资源,避免内存泄漏
            await Task.WhenAll(
                bossGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1)),
                workerGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1)));
        }
    }
}

// 自定义Handler,负责接收并展示客户端消息
public class MessageDisplayHandler : SimpleChannelInboundHandler<string>
{
    // 收到客户端消息时触发
    protected override void ChannelRead0(IChannelHandlerContext context, string message)
    {
        Console.WriteLine($"收到客户端[{context.Channel.RemoteAddress}]的消息:{message}");
        // 如果需要回复客户端,取消下面注释即可
        // await context.WriteAndFlushAsync($"服务器已收到消息:{message}");
    }

    // 客户端连接成功时的回调
    public override void ChannelActive(IChannelHandlerContext context)
    {
        Console.WriteLine($"客户端[{context.Channel.RemoteAddress}]已连接");
        base.ChannelActive(context);
    }

    // 客户端断开连接时的回调
    public override void ChannelInactive(IChannelHandlerContext context)
    {
        Console.WriteLine($"客户端[{context.Channel.RemoteAddress}]已断开连接");
        base.ChannelInactive(context);
    }

    // 处理异常情况
    public override void ExceptionCaught(IChannelHandlerContext context, Exception exception)
    {
        Console.WriteLine($"服务器发生异常:{exception.Message}");
        _ = context.CloseAsync();
    }
}

关键注意事项

  • 编码一致性:客户端用Encoding.Default将字符串转字节,服务器的StringDecoder必须使用相同的编码,否则会出现乱码问题
  • 资源释放:服务器的MultithreadEventLoopGroup一定要在最后优雅关闭,否则会造成资源泄漏
  • 客户端异常处理:原代码的catch块是空的,建议添加错误日志,方便排查连接失败的原因
  • 连接关闭:客户端发送完消息后要调用Shutdown关闭连接,否则服务器可能会一直等待客户端发送更多数据

内容的提问来源于stack exchange,提问作者user5405648

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:02:24