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("\r")[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);
};
DelimiterDataReceived和DataReceived内部使用了两个不同的字节链表,解析起来互不影响。这两个事件的处理程序中尽量不要做耗时的操作,否则会影响后续的数据接收。
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("\r")[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();
总结
上面的代码主要为了展示库的功能,实际使用时可能就几行代码,性能要求不高的项目都可以使用。
项目和库的源码链接如下:
C#开源类库SimpleTCP的更多相关文章
- Atitit java onvif 开源类库 getProfiles getStreamUri
Atitit java onvif 开源类库 getProfiles getStreamUri 1. ONVIF Java Library by Milgo1 1.1. https://github. ...
- 一些iOS高效开源类库
因为iOS SDK相对比较底层,所以开发者就得受累多做一些体力活.不过幸运的是,有很多第三方的类库可以用来简化很多不必要的工作.笔者整理了一下在本人学习过程中用到的一些比较有用Objective-C开 ...
- dropzonejs中文翻译手册 DropzoneJS是一个提供文件拖拽上传并且提供图片预览的开源类库.
http://wxb.github.io/dropzonejs.com.zh-CN/dropzonezh-CN/ 由于项目需要,完成一个web的图片拖拽上传,也就顺便学习和了解了一下前端的比较新的技术 ...
- [转]C#常用开源类库收集
.net PDF 类库 PDFsharp PDFsharp是一款可以让.NET框架支持的任何语言很容易的创建PDF文件的类库. ASP.NET FO PDF FO PDF 是一款C#编写类似于ASP. ...
- C#常用开源类库
一.AOP框架 Encase 是C#编写开发的为.NET平台提供的AOP框架.Encase 独特的提供了把方面(aspects)部署到运行时代码,而其它AOP框架依赖配置文件的方式.这种 ...
- Json序列化之.NET开源类库Newtonsoft.Json的研究
一.Json简介 JSON(全称为JavaScript Object Notation) 是一种轻量级的数据交换格式.它是基于JavaScript语法标准的一个子集. JSON采用完全独立于语言的文 ...
- 【转】java开源类库pinyin4j的使用
最近CMS系统为了增加查询的匹配率,需要增加拼音检索字段,在网上找到了pinyin4j的java开源类库,提供中文转汉语拼音(并且支持多音字), 呵呵,看了看他的demo,决定就用它了,因为我在实际使 ...
- 使用CocoaPods管理第三方开源类库
iOS开发中经常会用到许多第三方开源类库,比如AFNetworking.FMDB.JSONKit等等,使用CocoaPods这个工具就能很方便得对工程中用到的类库进行管理,包括自动下载配置以及更新. ...
- Java 的 JSON 开源类库选择比较(zz)
在看了作者的介绍,然后我又到mvnrepository上去看了各个库的的使用数之后,发现只能在jackson和gson之间做选择. 以下是原文 有效选择七个关于Java的JSON开源类库 April ...
随机推荐
- 白话JavaScript原型链和继承
原型基础 每个函数都有一个prototype属性,指向函数的原型对象 每个对象都一个私有属性 __proto__, 默认指向其构造函数的prototype 在JS中所有函数都是Function构造出来 ...
- 为了彻底搞懂 hashCode,我钻了一下 JDK 的源码
今天我们来谈谈 Java 中的 hashCode() 方法--通过源码的角度.众所周知,Java 是一门面向对象的编程语言,所有的类都会默认继承自 Object 类,而 Object 的中文意思就是& ...
- ElasticSearch进阶检索
ElasticSearch进阶检索 入门检索中讲了如何导入elastic提供的样本测试数据,下面我们用这些数据进一步检索 一.SearchAPI ES 支持两种基本方式检索 : 1.一种是通过使用 R ...
- Java面向对象12——static详解
static package oop.demon01.demon07; // static : public class Student { private static int a ...
- Hello World!!
已经工作了一年多,现在才开始写博客.话说,种一棵树最好的时机是十年前,其次是现在,我觉得不迟.俗话说滴水穿石,我想把一些东西,都慢慢积累起来,看见自己的成长.既方便查看,更不容易忘记.可能在网上已经有 ...
- JavaScript学习06(操作BOM和表单)
操作BOM window 所有浏览器都支持 window 对象.它代表浏览器的窗口. 所有全局 JavaScript 对象,函数和变量自动成为 window 对象的成员. 全局变量是 window 对 ...
- Linux 鸟叔的私房菜--完全结束
2018年10月22日 我不想再拖下去了,一本书看不完就无法进行下一本书的阅读,可能算是我的一个强迫症(借口吧) 之前看05年第一版<鸟叔的Linux私房菜>停在脚本语言那里,迟迟没有前进 ...
- Java 多线程与并发【知识点笔记】
Java 多线程与并发[知识点笔记] Java多线程与并发 先说一下线程与进程的由来: 在初期的计算机,计算机只能串行执行任务,并且需要长时间的等待用户的输入才行 到了后来,出现了批处理,可以预先将用 ...
- mock平台介绍和moco的简单例子
1.mock是什么?mock测试就是在测试过程中,对于某些不容易构造或者不容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法.在具体的测试过程中,我们经常会碰到需要模拟数据或者接口的情况,因为环 ...
- DVWA靶场之CSRF(跨站请求伪造)通关
Low: 服务器就看了password_new与password_conf是否相同,没有其他的验证 重新构造一个html页面,(自己假装自己是受害者,ip是靶场ip非本地ip) 1 <img s ...