C# 实现为Tcp服务器设计访问黑名单、白名单


一、说明

1.1 什么是黑白名单

黑名单的含义就是不允许黑名单上的ip地址对当前服务器进行访问。
白名单的含义就是只允许白名单上的ip地址访问当前服务器。

1.2 为什么要设计黑白名单?

因为可以有效杜绝其他人连接。将不正确连接,阻挡在传输层。

那么,按这个思路,让我们使用TouchSocket优雅的实现吧。


二、程序集源码

2.1 源码位置
2.2 说明文档

文档首页

三、安装

Nuget安装TouchSocket即可,具体步骤详看链接博客。

VS、Unity安装和使用Nuget包

四、声明限制访问判断类

用接口实现的好处是,实例可以自由实现,比如使用数据库实现,能够实现持久化限制访问名单。

 public interface IAccessRestrictions
 {
     bool AddWhiteList(string ip);

     bool AddBlackList(string ip);

     bool RemoveWhiteList(string ip);

     bool RemoveBlackList(string ip);

     bool ExistsWhiteList(string ip);

     bool ExistsBlackList(string ip);
 }

 public class AccessRestrictions : IAccessRestrictions
 {
     private readonly List<string> m_whiteListIP = new List<string>();
     private readonly List<string> m_blackListIP = new List<string>();

     public virtual bool AddBlackList(string ip)
     {
         if (this.m_blackListIP.Contains(ip))
         {
             return true;
         }
         this.m_blackListIP.Add(ip);
         return true;
     }

     public virtual bool AddWhiteList(string ip)
     {
         if (this.m_whiteListIP.Contains(ip))
         {
             return true;
         }
         this.m_whiteListIP.Add(ip);
         return true;
     }

     public virtual bool ExistsBlackList(string ip)
     {
         //实际上此处也可以用正则表达式
         return this.m_blackListIP.Contains(ip);
     }

     public virtual bool ExistsWhiteList(string ip)
     {
         //实际上此处也可以用正则表达式
         return this.m_whiteListIP.Contains(ip);
     }

     public virtual bool RemoveBlackList(string ip)
     {
         return this.m_blackListIP.Remove(ip);
     }

     public virtual bool RemoveWhiteList(string ip)
     {
         return this.m_whiteListIP.Remove(ip);
     }
 }

五、声明插件

使用插件,可以很好的隔离处理逻辑。

public class AccessRestrictionsPlugin : PluginBase, ITcpConnectingPlugin<ITcpClientBase>
{
    private readonly IAccessRestrictions accessRestrictions;

    public AccessRestrictionsPlugin(IAccessRestrictions accessRestrictions)
    {
        this.accessRestrictions = accessRestrictions ?? throw new ArgumentNullException(nameof(accessRestrictions));
    }

    public Task OnTcpConnecting(ITcpClientBase client, ConnectingEventArgs e)
    {
        if (client.IsClient)
        {
            //此处判断,如果该插件被添加在客户端,则不工作。
            return e.InvokeNext();
        }
        if (this.accessRestrictions.ExistsWhiteList(client.IP))
        {
            //如果存在于白名单,直接返回,允许连接
            return e.InvokeNext();
        }
        if (this.accessRestrictions.ExistsBlackList(client.IP))
        {
            //如果存在于黑名单,不允许连接
            e.IsPermitOperation = false;
            e.Handled = true;//表示此处已经处理OnConnecting消息,其他插件不再路由投递。
            return Task.CompletedTask;
        }

        return e.InvokeNext();
    }
}

六、创建服务器

var service = new TcpService();
service.Received = (client, byteBlock, requestInfo) =>
{
    //从客户端收到信息
    var mes = Encoding.UTF8.GetString(byteBlock.Buffer, 0, byteBlock.Len);
    client.Logger.Info($"已从{client.Id}接收到信息:{mes}");
};

service.Setup(new TouchSocketConfig()//载入配置
    .SetListenIPHosts("tcp://127.0.0.1:7789",7790)//同时监听两个地址
    .ConfigureContainer(a =>//容器的配置顺序应该在最前面
    {
        a.AddConsoleLogger();//添加一个控制台日志注入(注意:在maui中控制台日志不可用)

        //注册访问限制实例,AccessRestrictions可自行实现,例如连接数据库做持久化等。
        a.RegisterSingleton<IAccessRestrictions, AccessRestrictions>();
    })
    .ConfigurePlugins(a =>
    {
        a.Add<AccessRestrictionsPlugin>();//添加访问限制插件
    }))
    .Start();//启动

service.Logger.Info("服务器成功启动");

本文示例demo

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

若汝棋茗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值