zoukankan      html  css  js  c++  java
  • C#开源类库SimpleTCP

    简介

    工作中经常遇到需要实现TCP客户端或服务端的时候,如果每次都自己写会很麻烦且无聊,使用SuperSocket库又太大了。这时候就可以使用SimpleTCP了,当然仅限于C#语言。

    SimpleTCP是一个简单且非常有用的 .NET 库,用于处理启动和使用 TCP 套接字(客户端和服务器)的重复性任务,使用起来非常方便、代码也少。它的内部不是直接使用的Socket,而是在TcpClient的基础上进行了再次封装,接口更简单、明了。

    它的主要特点如下:

    • 源码简单:源码就几个类,每个类也不大,在了解TcpClient用法的基础上不需要注释就可以看懂。
    • 功能单一:不像其它库一样功能繁多,它只专注于实现简单的TCP客户端、服务端,使用起来不用担心增加系统的复杂性。
    • 使用简单:后面的示例会具体讲解,启动一个客户端或服务端只需要几行代码,想扩展功能也很简单。

    说一下它的不足之处(在我看来完全可以接受):

    • 已停止更新:最后更新时间是2017年,不过库的功能比较简单、单一,也没那么多更新的内容。
    • 性能不是最优的:底层是基于TcpClient的,性能注定不会太高,但能用TcpClient的地方都可以用它。

    使用方法

    在项目中直接引用SimpleTCP.dll即可, dll文件可以通过NuGet安装或从github下载源码编译。
    SimpleTCP内部有一个特殊字符分割字符串的协议可以直接使用,也可以在DataReceived事件处理程序中实现自己的协议。

    实现客户端

    实现一个客户端的代码如下:

    //初始化
    var client = new SimpleTcpClient();            
    
    //设置编码格式,默认是UTF8
    client.StringEncoder = System.Text.ASCIIEncoding.ASCII;
    //设置分隔符,默认是0x13
    client.Delimiter = Encoding.ASCII.GetBytes("
    ")[0];
    
    //收到分割数据的事件,遇到分隔符就会触发事件
    client.DelimiterDataReceived += (sender, msg) => 
    {
        Console.WriteLine("DelimiterStr-"+DateTime.Now.ToString()+ msg.MessageString);
    };
    
    //收到数据的事件,可以在这里实现自己的协议
    client.DataReceived += (sender, msg) => 
    {
        //字节数组
        Console.WriteLine("Data:"+BitConverter.ToString(msg.Data));
        //字符串消息
        Console.WriteLine("ReceivedStr:" + msg.MessageString);
    };
    

    DelimiterDataReceivedDataReceived内部使用了两个不同的字节链表,解析起来互不影响。这两个事件的处理程序中尽量不要做耗时的操作,否则会影响后续的数据接收

    SimpleTCP没有心跳、重连功能,也没找到反馈客户端连接状态的属性(不建议使用内部TcpClient的连接状态)。我们可以直接扩展这些功能,代码如下:

    bool exit = false;
    bool connected = false;
    Task.Factory.StartNew(() => 
    {
        while (!exit) 
        {
            try
            {
                if (connected)
                {
                    //发送心跳
                    client.Write("");
                    Task.Delay(10000).Wait();
                }
                else
                {
                    //断线重连
                    client.Connect("127.0.0.1", 4196);
                    connected = true;
                    Task.Delay(1000).Wait();
                }
            }
            catch (Exception)
            {
                connected = false;
                client.Disconnect();
            }
        }               
        
    }, TaskCreationOptions.LongRunning);
    

    把上面的代码按顺序复制到控制台的Main函数中,然后加入下面的代码就可以收发数据了:

    while (true) 
    {
        string strLine = Console.ReadLine();
        if (strLine == "esc") 
        {
            exit = true;
            client.Disconnect();
            return;
        }
        if (connected) 
        { 
            //获取服务端回复的消息,最多等待3秒,收到消息时会提前返回
            //也可以使用Write、WriteLine方法发送数据,WriteLine会自动在后面加上设置的分隔符
            var replyMsg = client.WriteLineAndGetReply(strLine, TimeSpan.FromSeconds(3));
            if (replyMsg != null) 
            {
                Console.WriteLine(replyMsg);
            }
        }
    }
    

    注:WriteLineAndGetReply内部使用的是DataReceived,不会自动去除分隔符

    实现服务端

    服务端功能比较简单,把收到分割数据加工后返回客户端,代码如下:

    //初始化
    var server = new SimpleTcpServer();
    //设置编码格式,默认是UTF8
    server.StringEncoder = System.Text.ASCIIEncoding.ASCII;
    server.Delimiter =  Encoding.ASCII.GetBytes("
    ")[0];
    
    //分割数据接收事件
    server.DelimiterDataReceived += (sender, msg) => 
    {
        Console.WriteLine(msg.TcpClient.Client.RemoteEndPoint.ToString()+":" + msg.MessageString);
        msg.ReplyLine("Reply-" + msg.MessageString);
    };
    
    //数据接收数据
    server.DataReceived += (sender, msg) =>
    {
        Console.WriteLine(msg.TcpClient.Client.RemoteEndPoint.ToString() + ":" + msg.MessageString);
    };
    
    //客户端连接事件
    server.ClientConnected += (sender, msg) => 
    {
        Console.WriteLine("ClientConnected:" + msg.Client.RemoteEndPoint.ToString());
    };
    
    //客户端断开事件
    server.ClientDisconnected += (sender, msg) =>
    {
        Console.WriteLine("ClientDisconnected:" + msg.Client.RemoteEndPoint.ToString());
    };
    
    //开始监听
    server.Start(4196);
    //监听的IP
    var listeningIps = server.GetListeningIPs();
    //监听的V4Ip
    var listeningV4Ips = server.GetListeningIPs().Where(ip => ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork);
    
    
    
    Task.Factory.StartNew(() =>
    {
        while (true)
        {   
            //连接数监控
            int clientsConnected = server.ConnectedClientsCount;
            Console.WriteLine("当前连接的客户端数:" + clientsConnected);
            Task.Delay(10000).Wait();
        }
    
    }, TaskCreationOptions.LongRunning);            
    Console.ReadLine();
    
    //停止监听
    server.Stop();
    Console.WriteLine("停止服务端!");
    Console.ReadLine();
    

    总结

    上面的代码主要为了展示库的功能,实际使用时可能就几行代码,性能要求不高的项目都可以使用。

    项目和库的源码链接如下:

  • 相关阅读:
    Delphi XE5 android 蓝牙通讯传输
    Delphi XE5 android toast
    Delphi XE5 android openurl(转)
    Delphi XE5 如何设计并使用FireMonkeyStyle(转)
    Delphi XE5 android 捕获几个事件
    Delphi XE5 android listview
    Delphi XE5 android 黑屏的临时解决办法
    Delphi XE5 android popumenu
    Delphi XE5 android 获取网络状态
    Delphi XE5 android 获取电池电量
  • 原文地址:https://www.cnblogs.com/timefiles/p/CSharpSimpleTCP.html
Copyright © 2011-2022 走看看